Class that is able to perform dynamic dispatch on multiple functions with one parameter.
More...
Public Member Functions |
| SingleDispatcher (bool supportDerivedToBase=false) |
| Default constructor.
|
template<class D > |
void | Register (R(*globalFunction)(D#)) |
| Registers a global function.
|
template<class D , class C > |
void | Register (R(C::*memberFunction)(D#), C &object) |
| Registers a member function.
|
template<class D , typename Fn > |
void | Register (const Fn &functionObject) |
| Registers a function object.
|
R | Call (B arg) const |
| Dispatches the dynamic type of arg and invokes the corresponding function.
|
template<class B, typename R = void>
class thor::SingleDispatcher< B, R >
Class that is able to perform dynamic dispatch on multiple functions with one parameter.
Sometimes you encounter the situation where you need to implement polymorphic behavior, but you cannot or don't want to add a virtual function to an existing class hierarchy. Here comes dynamic dispatch into play: You define free functions, which can be treated by the dispatcher like virtual functions.
- Template Parameters:
-
B | Reference or pointer to polymorphic class, which is the base class of every dispatched function's parameter type. When B is a pointer, the arguments of the dispatched functions shall be pointers too (the same applies to references). If B is a pointer or reference to const, the dispatched functions cannot modify their arguments. In this case, the dispatched functions shall have arguments of type pointer or reference to const, too. |
R | Return type of the dispatched functions. |
class Base { public: virtual ~Base() {} };
class Derived1 : public Base {};
class Derived2 : public Base {};
void Func(Derived1* d);
void Func(Derived2* d);
thor::SingleDispatcher<Base*> dispatcher;
dispatcher.Register<Derived1>(&Func);
dispatcher.Register<Derived2>(&Func);
Base* ptr = new Derived1;
dispatcher.Call(ptr);
delete ptr;
template<class B, typename R = void>
Dispatches the dynamic type of arg and invokes the corresponding function.
Note that the argument's dynamic type must match exactly with the registered type, unless you enabled derived-to-base conversions in the constructor and specified the class hierarchy. In the latter case, the function with the best match is chosen for overload resolution.
- Parameters:
-
arg | Function argument as a reference or pointer to the base class. |
- Returns:
- The return value of the dispatched function, if any.
- Exceptions:
-
template<class B, typename R = void>
template<class D >
Registers a global function.
- Template Parameters:
-
D | Type of the derived class. Must be explicitly specified. |
- Parameters:
-
globalFunction | Pointer to function to register. |
Note that # is a placeholder for either & or *. The type D# has the same attributes as B (pointer, reference, const-qualification): For instance, B=const Base& implies D#=const Derived1&.
Example (class hierarchy and dispatcher declaration missing):
void Func(Derived1&);
void Func(Derived2&);
dispatcher.Register<Derived1>(&Func);
dispatcher.Register<Derived2>(&Func);
- Precondition:
- A function taking an argument of dynamic type D is not registered yet.
template<class B, typename R = void>
template<class D , class C >
Registers a member function.
- Template Parameters:
-
D | Type of the derived class. Must be explicitly specified. |
C | Class that holds the member function. |
- Parameters:
-
memberFunction | Pointer to member function to register. |
object | Reference to the object on which the member function is invoked. |
Note that # is a placeholder for either & or *. The type D# has the same attributes as B (pointer, reference, const-qualification): For instance, B=const Base& implies D#=const Derived1&.
Example (class hierarchy and dispatcher declaration missing):
struct MyClass
{
void MemFunc(Derived1&);
void MemFunc(Derived2&);
} obj;
dispatcher.Register<Derived1>(&MyClass::MemFunc, obj);
dispatcher.Register<Derived2>(&MyClass::MemFunc, obj);
- Precondition:
- A function taking an argument of dynamic type D is not registered yet.
template<class B, typename R = void>
template<class D , typename Fn >
Registers a function object.
- Template Parameters:
-
D | Type of the derived class. Must be explicitly specified. |
Fn | Type of the function object. Can be deduced from the argument. |
- Parameters:
-
functionObject | Functor to register. |
Incomplete example using a function object (you can also have separate functors for each function):
struct Functor
{
void operator() (Derived1&);
void operator() (Derived2&);
};
dispatcher.Register<Derived1>(Functor());
dispatcher.Register<Derived2>(Functor());
- Precondition:
- A function taking an argument of dynamic type D is not registered yet.