質問

I am trying to create a very simple event system to be used in a game. I have a EventManager class that looks something like this:

typedef std::function<void(IEvent* event)> CallbackType;

class EventManager
{
public:
    void AddListener(const std::string eventName, IEventListener* listener)
    {
        CallbackType callback = std::bind(&IEventListener::HandleEvent, listener, std::placeholders::_1);

        listeners[eventName].push_back(callback);
    }

    void AddListener(const std::string eventName, CallbackType callback)
    {
        // ...
    }

    void TriggerEvent(IEvent* event)
    {
        for (CallbackType callback : listeners[event->GetName()])
        {
            callback(event);
        }
    }
private:
    std::map<std::string, std::vector<CallbackType>> listeners;
}

The 1st AddListener function works perfectly. The TriggerEvent function calls the HandleEvent function, which is implemented by each class that extends my IEventListener interface.

I would really like to be able to pass a callback to the 2nd AddListener function. This callback would then get called in the TriggerEvent function as before. I can pass in a callback constructed using std::bind and this works. For example:

eventManager->AddListener("WindowResize", std::bind(&MyClass::MemberFunction, this, std::placeholders::_1));

where MyClass extends the IEventListener interface. However, I'd really like to be able to just pass a simple function pointer instead:

eventManager->AddListener("WindowResize", this, &MyClass::MemberFunction);

Is this possible?

Edit

For anyone interested, I wrote a couple of macros that I think makes things a little cleaner.

#define MEMBER_CALLBACK(funPtr) \
std::bind(&funPtr, this, std::placeholders::_1)

#define MEMBER_CALLBACK_WITH_INSTANCE(funPtr, instancePtr) \
std::bind(&funPtr, instancePtr, std::placeholders::_1)

Now I can subscribe to an event by:

eventManager->AddListener("EventName", MEMBER_CALLBACK(MyClass::MemberFunction));
役に立ちましたか?

解決

You can't pass a simple function pointer because MyClass::MemberFunction isn't a simple function. The std::bind() works because it associates an instance of MyClass with the reference to the member function. Without that information, the member function would not have access to the instance's data.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top