It seems you want to use std::function
, I would say something like:
class Base
{
public:
struct EventContext
{
int data1;
};
Base() {}
virtual int ProcessEvent(std::string event, EventContext ctx) =0;
protected:
typedef std::function<int(const EventContext&)> HandlerType;
typedef std::map<std::string, HandlerType> EventDelegateMap;
EventDelegateMap _delegates;
};
class Derived: Base
{
public:
Derived();
int ProcessEvent(std::string event, EventContext ctx){ return 0; }
private:
int FooEventHandler(const EventContext& context){ return 0; }
int BarEventHandler(const EventContext& context){ return 0; }
int QuxEventHandler(const EventContext& context){ return 0; }
};
Derived::Derived() :Base()
{
auto self = this; // Some gcc versions cannot capture this correctly.
_delegates["foo"] = [=](const EventContext& context) { return self->FooEventHandler(context); };
_delegates["bar"] = [=](const EventContext& context) { return self->BarEventHandler(context); };
_delegates["qux"] = [=](const EventContext& context) { return self->QuxEventHandler(context); };
}
Ought to work...
EDIT: As @Joachim mentions in his comment, you can use std::bind()
to generate the required std::function
object too, e.g.
_delegates["foo"] = std::bind(&Derived::FooEventHandler, this, std::placeholders::_1);
I used the lambda to show that in reality, you can implement the entire logic in the lambda. The primary advantage of this approach is that if you are implementing more handlers, it's less effort and I'm always in favour of less effort... :)