BOOST_OPENMETHOD_OVERRIDE

Add an overrider to a method.

Synopsis

Declared in <boost/openmethod/macros.hpp>

#define BOOST_OPENMETHOD_OVERRIDE(ID, PARAMETERS, …​)

Description

BOOST_OPENMETHOD_OVERRIDE adds an overrider to a method. It is followed by the overrider's body.

ID is the identifier of the method to which the overrider is added.

PARAMETERS is a comma‐separated list of types, possibly followed by parameter names, just like in a function declaration.

The macro tries to locate a method that can be called with the same argument list as the overrider, possibly via argument dependent lookup.

Each virtual_ptr<T> in the method's parameter list must have a corresponding virtual_ptr<U> parameter in the same position in the overrider's parameter list, such that U is the same as T, or has T as an accessible unambiguous base.

Each virtual_<T> in the method's parameter list must have a corresponding U parameter in the same position in the overrider's parameter list, such that U is the same as T, or has T as an accessible unambiguous base.

The following names are available inside the overrider's body:

  • fn: a pointer to a function, the overrider itself. Can be used for recursion.

  • next: a function with the same signature as the method (minus the virtual_<> decorators). It forwards to the next most specialized overrider, if it exists and it is unique. If the next overrider does not exist, or is ambiguous, calling next reports a boost::openmethod::no_overrider or a boost::openmethod::ambiguous_call and terminates the program.

  • has_next(): returns true if the next most specialized overrider exists.

ID must be an identifier. Qualified names are not allowed.

Example

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

BOOST_OPENMETHOD_OVERRIDE(
    poke, (virtual_ptr<Cat> animal, std::ostream& os), void) {
    os << "hiss";
}

BOOST_OPENMETHOD_OVERRIDE(
    poke, (virtual_ptr<Dog> animal, std::ostream& os), void) {
    os << "bark";
}

Cat felix;
Animal& a = felix;
Dog snoopy;
Animal& b = snoopy;

poke(a, std::cout); // hiss
poke(b, std::cout); // bark

Implementation Notes

The macro creates additional entities in the current scope.

  • A class template declaration that acts as a container for the method's overriders in the current scope:

template<typename...> struct BOOST_OPENMETHOD_OVERRIDERS(ID);
  • A specialization of the container for the overrider:

struct BOOST_OPENMETHOD_OVERRIDERS(ID)<RETURN_TYPE(PARAMETERS...)> {
    static auto fn(PARAMETERS...) -> RETURN_TYPE;
    static auto has_next() -> bool;
    template<typename... Args>
    static auto next(typename... Args) -> RETURN_TYPE;
};
  • A registrar (see BOOST_OPENMETHOD_REGISTER) adding the overrider to the method.

  • Finally, the macro starts the definition of the overrider function:

auto BOOST_OPENMETHOD_OVERRIDERS(ID)<RETURN_TYPE(PARAMETERS...)>::fn(
    PARAMETERS...) -> RETURN_TYPE

The {} block following the call to the macro is the body of the function.

Parameters

Name

Description

ID

The method's name.

PARAMETERS

The overrider's parameter list, in parentheses.

...

The overrider's return type.