boost::openmethod::method :: Boost.OpenMethod

# boost::openmethod::method

Implement a method

## Synopsis

Declared in `<boost/openmethod/core.hpp>`

    template<
        typename Id,
        typename Fn,
        class Registry = boost::openmethod::default_registry>
    class method;

## Description

Methods are created by specializing the `method` class template with an identifier, a function type and optionally a registry.

`Id` is a type, typically an incomplete class declaration named after the method's purpose. It is used to allow different methods with the same signature.

`Fn` is a function type, i.e. a type in the form `ReturnType(Parameters...)`.

`Registry` is an instantiation of class template `registry`. Methods may use only classes that have been registered in the same registry as virtual parameters and arguments. The registry also contains a set of policies that influence several aspects of the dispatch mechanism ‐ for example, how to acquire a v‐table pointer for an object, how to report errors, whether to perform sanity checks, etc.

The default value for `Registry` is `default_registry`, but it can be overridden by defining the preprocessor symbol BOOST_OPENMETHOD_DEFAULT_REGISTRY, before including `<boost/openmethod/core.hpp>`. Setting the symbol afterwards has no effect.

Specializations of `method` have a single instance: the static member `fn`, which has an `operator()` that forwards to the appropriate overrider. It is selected in the same way as overloaded function resolution:

1. Form the set of all applicable overriders. An overrider is applicable if it can be called with the arguments passed to the method.

2. If the set is empty, call the error handler (if present in the registry), then terminate the program with `abort`.

3. Remove the overriders that are dominated by other overriders in the set. Overrider A dominates overrider B if at least one of its virtual formal parameters is more specialized than B's, and if none of B's virtual parameters is more specialized than A's.

4. If the resulting set contains exactly one overrider, call it.

If a single most specialized overrider does not exist, the program is terminated via `abort`. If the registry contains an `error_handler` policy, its `error` function is called with an object that describes the error, prior calling `abort`. `error` may prevent termination by throwing an exception.

For each virtual argument `arg`, the dispatch mechanism calls `virtual_traits::peek(arg)` and deduces the v‐table pointer from the `result`, using the first of the following methods that applies:

1. If `result` is a `virtual_ptr`, get the pointer to the v‐table from it.

2. If `boost_openmethod_vptr` can be called with `result` and a `Registry*`, and it returns a `vptr_type`, call it.

3. Call `Registry::rtti::dynamic_vptr(result)`.

## N2216 Handling of Ambiguous Calls

If `Registry` was initialized with the `N2216` option, ambiguous calls are not an error. Instead, the following extra steps are taken to select an overrider:

1. If the return type is a registered polymorphic type, remove all the overriders that return a less specific type than others.

2. If the resulting set contains only one overrider, call it.

3. Otherwise, call one of the remaining overriders. Which overrider is selected is not specified, but it is the same across calls with the same arguments types.

## Template Parameters

Name | Description
--- | ---
Id | A type
Fn | A function type
Registry | The registry in which the method is defined

Created with MrDocs