![]() |
Boost : |
From: Jean-Louis Leroy (jl_at_[hidden])
Date: 2025-03-10 20:45:13
>
> > One thing I asked myself reading the doc, was the handling of const-ness
> in
> > method signatures, whether it was supported or not, and if it was,
> > consequences on overloading.
>
> `const` is supported. Some examples use it (e.g.
> https://github.com/jll63/Boost.OpenMethod/blob/master/examples/matrix.cpp
> ).
>
> > Another question I had relates to Steven's Boost.TypeErasure, and
> similarities
> > / differences with your approach. Naively I'd think there was some
> overlap, at
> > least for single-dispatch, no?
>
> First a disclaimer: I am not very familiar with Boost.TypeErasure. If I
> make
> incorrect claims about it, I apologize in advance, and please do correct
> me.
>
> The two libraries are obviously in the same space: runtime polymorphism,
> and a
> solution to the Expression Problem (thanks to BOOST_TYPE_ERASURE_FREE).
> There
> are some major differences though, and I suspect that they can be counted
> in
> favor, or against, either library, depending on one's distate for
> inheritance. I
> will go over them starting with the more important then down.
>
> As far as I can tell, TypeErasure, Rust traits and Go interfaces don't
> support
> open recursion. You are granted one jump through an `any`, and you land in
> an
> overrider with a plain reference. You lose polymorphism the first time
> through
> the door.
>
> Related to this, objects returned from overriders have no means of
> carrying the
> functionality that may have initially existed in the any/trait/interface.
> Let's
> look at an example.
>
> #include <iostream>
> #include <
> https://jll63.github.io/Boost.OpenMethod/boost/openmethod.hpp>
>
> struct Matrix { virtual ~Matrix() = default; };
> struct OrdinaryMatrix : Matrix {};
> struct SymmetricMatrix : Matrix {};
>
> using namespace boost::openmethod;
>
> BOOST_OPENMETHOD_CLASSES(Matrix, OrdinaryMatrix, SymmetricMatrix);
>
> BOOST_OPENMETHOD(
> transpose, (shared_virtual_ptr<Matrix>),
> shared_virtual_ptr<Matrix>);
>
> BOOST_OPENMETHOD_OVERRIDE(
> transpose, (shared_virtual_ptr<OrdinaryMatrix>),
> shared_virtual_ptr<Matrix>) {
> return make_shared_virtual<OrdinaryMatrix>();
> }
>
> BOOST_OPENMETHOD_OVERRIDE(
> transpose, (shared_virtual_ptr<SymmetricMatrix> m),
> shared_virtual_ptr<Matrix>) {
> return m;
> }
>
> BOOST_OPENMETHOD(
> to_json, (shared_virtual_ptr<Matrix>), std::string);
>
> BOOST_OPENMETHOD_OVERRIDE(
> to_json, (shared_virtual_ptr<OrdinaryMatrix> m),
> std::string) {
> return "JSON for ordinary matrix";
> }
>
> BOOST_OPENMETHOD_OVERRIDE(
> to_json, (shared_virtual_ptr<SymmetricMatrix> m), std::string) {
> return "JSON for a symmetric matrix\n";
> }
>
> int main() {
> initialize();
>
> auto m = make_shared_virtual<SymmetricMatrix>();
> auto t = transpose(m);
> std::cout << to_json(t) << "\n";
>
> return 0;
> }
>
> (https://godbolt.org/z/xG91rfqGr)
>
> Transposition, addition, etc are clearly part of a matrix API, whereas
> `to_json`
> is a cross-cutting concern. With open-methods, we can _add_ the "jsonable"
> functionality to _Matrix_ - even though we don't touch the source.
>
> I guess that a translation of this example to `any` (or Rust) would look
> like
> this: have a MatrixType concept that states that matrices can be
> transposed (and
> added, etc). We can also add a concept, say, JsonSerializable stating that
> a
> Matrix can be converted to a JSON string. Can we make
> `to_json(transpose(m))`
> work? Without making MatrixType aware of JsonSerializable?
>
> So this is the major differences, but there are a few others...
>
> OpenMethod embraces inheritance. Some will dislike that. Live and let
> live...
>
> It looks like creating an `any` always requires a call to `new`. Storage is
> managed via a `std::shared_ptr`. OpenMethod can work with zero allocations
> after
> `initialize` has been called. Later I will introduce local sequential
> allocators
> for completely alloc-free operation.
>
> While the syntax of TypeErasure is really nice, I suspect that `any`
> declarations can become unwieldy in larger programs, in presence of a
> couple
> dozens of functions in the interface.
>
> Oh yes, I almost forgot: multiple dispatch indeed :)
>
> J-L
>
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk