Note

This section uses overrider containers, described in the Headers and Implementation Files section.

BOOST_OPENMETHOD defines a method in the current namespace. BOOST_OPENMETHOD_OVERRIDE works across namespaces. Overriders are not required to be in the same namespace as the method they override. The macro adds the overrider to a method that can be called with the same arguments as the overrider, possibly located via argument dependant lookup.

Overrider containers are added to the current namespace. It follows that the same method can have overriders in multiple containers, in different namespaces. This must be taken into account when calling an overrider explicitly. Let’s put Employee and Salesman in their own namespaces:

// roles.hpp

#ifndef ROLES_HPP
#define ROLES_HPP

#include <boost/openmethod.hpp>

namespace employees {

struct Employee {
    virtual ~Employee() = default;
};

BOOST_OPENMETHOD(pay, (boost::openmethod::virtual_ptr<const Employee>), double);

BOOST_OPENMETHOD_INLINE_OVERRIDE(
    pay, (boost::openmethod::virtual_ptr<const Employee>), double) {
    return 5000.0;
}

}

namespace sales {

struct Salesman : employees::Employee {
    double sales = 0.0;
};

} // namespace sales
#endif // ROLES_HPP

When we try to compile salesman.cpp:

BOOST_OPENMETHOD_OVERRIDE(
    pay, (boost::openmethod::virtual_ptr<const Salesman> emp), double) {
    return BOOST_OPENMETHOD_OVERRIDER(
               pay, (boost::openmethod::virtual_ptr<const Employee> emp),
               double)::fn(emp) +
        emp->sales * 0.05; // base + commission
}

We get an error like:

error: implicit instantiation of undefined template
'sales::pay_boost_openmethod_overriders<
    double (boost::openmethod::virtual_ptr<const employees::Employee>)>

This is because the overrider container for pay in namespace sales is specialized for Salesman, but not for Employee. The overrider for Employee is in a specialization of a different container, in namespace employees.

The solution is to qualify the overrider container with the employees namespace:

namespace sales {

BOOST_OPENMETHOD_OVERRIDE(
    pay, (boost::openmethod::virtual_ptr<const Salesman> emp), double) {
    return employees::BOOST_OPENMETHOD_OVERRIDER(
               pay, (boost::openmethod::virtual_ptr<const employees::Employee> emp),
               double)::fn(emp) +
        emp->sales * 0.05; // base + commission
}

BOOST_OPENMETHOD_CLASSES(employees::Employee, Salesman);

} // namespace sales