传递成员函数作为回调

C++ Passing a member function as a callback

本文关键字:回调 函数 成员      更新时间:2023-10-16

我正在尝试创建一个非常简单的事件系统,在游戏中使用。我有一个EventManager类,看起来像这样:

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;
}

第一个AddListener函数工作得很好。TriggerEvent函数调用HandleEvent函数,该函数由扩展我的IEventListener接口的每个类实现。

我真的希望能够传递回调到第二个AddListener函数。然后,这个回调会像以前一样在TriggerEvent函数中被调用。我可以传入一个用std::bind构造的回调函数,这样就可以了。例如:

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

其中MyClass扩展了IEventListener接口。然而,我真的希望能够传递一个简单的函数指针:

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

这可能吗?

编辑

对于任何感兴趣的人,我写了几个宏,我认为它们使事情变得更干净。

#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)

现在我可以订阅一个事件:

eventManager->AddListener("EventName", MEMBER_CALLBACK(MyClass::MemberFunction));

不能传递一个简单的函数指针,因为MyClass::MemberFunction不是一个简单的函数。std::bind()起作用是因为它将MyClass的实例与对成员函数的引用关联起来。如果没有这些信息,成员函数将无法访问实例的数据。