Boost logo

Boost :

From: Jean-Louis Leroy (jl_at_[hidden])
Date: 2025-05-24 22:36:44


During the review, Joaquin suggested changing the syntax for declaring and
overriding methods, from:

    BOOST_OPENMETHOD(poke, (virtual_ptr<Animal>, std::ostream&), void);

    BOOST_OPENMETHOD_OVERRIDE(
        poke, (virtual_ptr<Bulldog> dog, std::ostream& os), void) { ... }

to:

    BOOST_OPENMETHOD(poke, void(virtual_ptr<Animal>, std::ostream&));

    BOOST_OPENMETHOD_OVERRIDE(
        poke, void(virtual_ptr<Bulldog> dog, std::ostream& os)) { ... }

The difficulty with this is that the macros generate several constructs using
the method name, formal parameter list and return type.

Steven suggested a trick to implement a similar syntax, using trailing return
types:

    BOOST_OPENMETHOD(poke, (virtual_ptr<Animal>, std::ostream&)->void);

    BOOST_OPENMETHOD_OVERRIDE(
        poke, (virtual_ptr<Bulldog> dog, std::ostream& os)->void) { ... }

but I am not 100% sure if he actually _supports_ the change. @Steven, do you?

Personally, I like the above because it simplifies the macros. But it has a
couple of drawbacks.

1. `(virtual_ptr<Animal>, std::ostream&)->void` is not legal C++,
   `auto (virtual_ptr<Animal>, std::ostream&)->void` is. Isn't this going to
   cause confusion?

2. Count on MSVC to spoil things. If the return type is explicitly derived from
   a template, MSVC errors on it. Here is a reduction:

    #include <string>
    #include <tuple>

    template<typename> struct test{};

    using foo = test<auto (int)->std::string>;
    using bar = test<auto (int)->std::tuple<int>>; // MSVC fails on this
    using baz = test<auto (int)->decltype(std::tuple<int>())>; // workaround

Compiler Explorer: https://godbolt.org/z/MrbdYbW9Y It looks like a parser bug, I
reported it.

To all those who did _not_ suggest this change, if you oppose it, please let me
know.

J-L


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk