weak_dispatch
template <class D>
struct weak_dispatch : D; // since 3.2.0
Class template weak_dispatch<D>
extends an existing dispatch type D
and offers a default implementation of operator()
that throws not_implemented
when a convention is not implemented in D
.
Name | Description |
---|---|
(constructor) | constructs a weak_dispatch object |
(destructor) | destroys a weak_dispatch object |
operator() |
invokes the dispatch |
A “weak dispatch” can extend an existing dispatch with a default implementation that does not depend on the contained value of a proxy
object. This is useful when instantiating a proxy<F>
with a value that does not support some conventions defined by F
. Compared to wrapping the default implementation with PRO_DEF_FREE_DISPATCH
, using “weak dispatch” when applicable can effectively improve compilation speed and binary size, in case some contained value of a proxy
object does not participate code generation.
In Java or C#, a “default method” can invoke other abstract methods defined in a same interface
. This pattern is discouraged when using the Proxy library because the invocations are not necessarily indirect. If a “default implementation” otherwise needs to observe the contained value of a proxy
object, it is encouraged to define a separate free function, and subsequently define a dispatch type of it by using PRO_DEF_FREE_DISPATCH
or PRO_DEF_FREE_AS_MEM_DISPATCH
.
#include <iostream>
#include <string>
#include <vector>
#include "proxy.h"
PRO_DEF_MEM_DISPATCH(MemAt, at);
struct WeakDictionary : pro::facade_builder
::add_convention<pro::weak_dispatch<MemAt>, std::string(int index) const>
::build {};
int main() {
std::vector<const char*> v{"hello", "world"};
pro::proxy<WeakDictionary> p1 = &v;
std::cout << p1->at(1) << "\n"; // Prints "world"
pro::proxy<WeakDictionary> p2 = pro::make_proxy<WeakDictionary>(123);
try {
p2->at(1);
} catch (const pro::not_implemented& e) {
std::cout << e.what() << "\n"; // Prints an explanatory string
}
}