Skip to content

Instantly share code, notes, and snippets.

@dgodfrey206
Last active December 29, 2015 09:18
Show Gist options
  • Save dgodfrey206/7648972 to your computer and use it in GitHub Desktop.
Save dgodfrey206/7648972 to your computer and use it in GitHub Desktop.
Dispatching methods from instances.
#include <iostream>
#include <functional>
#include <string>
#include <map>
class X;
template<class X>
class dispatch_traits;
template<class X>
class handler_factory;
template<>
class dispatch_traits<X>
{
public:
using HandlerType = void (X::*)();
protected:
std::map<std::string, HandlerType> handlers;
HandlerType get(const std::string&) const
{
return nullptr;
}
};
template<>
class handler_factory<X> : dispatch_traits<X>
{
public:
handler_factory();
HandlerType get(const std::string& name) const;
};
class X
{
public:
friend class handler_factory<X>;
void dispatch_method(const std::string& name)
{
if (find_handle(name))
(this->*find_handle(name))();
}
private:
void f();
void h();
auto find_handle(const std::string& name)
-> decltype(handler_factory<X>{}.get(name))
{
return handler_factory<X>{}.get(name);
}
};
handler_factory<X>::handler_factory()
{
handlers["f"] = &X::f;
handlers["h"] = &X::h;
}
handler_factory<X>::HandlerType handler_factory<X>::get(const std::string& name) const
{
if (handlers.find(name) == handlers.end())
return dispatch_traits<X>::get(name);
else
return (*handlers.find(name)).second;
}
void X::f() { std::cout << "X::f();"; }
void X::h() { std::cout << "X::h();"; }
int main()
{
X x;
x.dispatch_method("f");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment