如何通过函数指针进行绑定?

时间:2019-04-20 04:38:11

标签: c++ c++11

我有以下代码:

_createNewObjectlistener = eventDispatcher->addCustomEventListener(Constants::EVENT_CREATE_OBJECT, std::bind(&ObjectPlacementManager::receiveCreateObjectEvent, this, std::placeholders::_1));
_eventListeners.insert(_createNewObjectlistener);

_moveNewObjectlistener = eventDispatcher->addCustomEventListener(Constants::EVENT_MOVE_NEW_OBJECT, std::bind(&ObjectPlacementManager::receiveMoveCurrentGameObjectEvent, this, std::placeholders::_1));
_eventListeners.insert(_moveNewObjectlistener);

.... many more listeners created

由于每个侦听器的创建代码之间唯一的区别是Constant::EVENT_NAME和被调用的函数,因此我试图将其封装为一个函数。

bind的结果必须为const std::function<void(EventCustom*)>&类型的

ObjectPlacementManager::receiveMoveCurrentGameObjectEvent之类的函数均具有相同的签名:

void receiveMoveCurrentGameObjectEvent(EventCustom* event){
 ....
}

我已经尝试过:How to pass argument to std::bind to a function?

typedef void (*callback_function)(EventCustom*);

EventListenerCustom* createCustomListener(callback_function func, std::string EVENT){
    auto eventDispatcher = _dragNode->getEventDispatcher();
    auto listener = eventDispatcher->addCustomEventListener(EVENT, std::bind(&func, this, std::placeholders::_1));
    _eventListeners.insert(_createNewObjectlistener);
    return listener;
}

但是我得到的错误是:

No viable conversion from '__bind<void (**)(cocos2d::EventCustom *), bejoi::ObjectPlacementManager *, const std::__1::placeholders::__ph<1> &>' to 'const std::function<void (EventCustom *)>'

我也尝试过创建一个函数:

EventListenerCustom* createCustomListener(void* func, std::string EVENT){
    auto eventDispatcher = _dragNode->getEventDispatcher();
    auto listener = eventDispatcher->addCustomEventListener(EVENT, std::bind(func, this, std::placeholders::_1));
    return listener;
}

但是我得到的错误是:

No viable conversion from '__bind<void *&, mynamespace:: ObjectPlacementManager *, const std::__1::placeholders::__ph<1> &>' to 'const std::function<void (EventCustom *)>'

1 个答案:

答案 0 :(得分:1)

第一个错误是因为您要获取函数指针的地址。因此,您正在将指向函数的指针的指针传递给std::bind

第二个错误是因为您使用了void *并且以某种方式希望它能正常工作!

尝试此MCVE:

struct Event {};

struct Dispatcher {
  void addListener(int, const std::function<void(Event *)> &) {}
};

struct Manager {
  void receive(Event *) {}

  void addListener(int type, void (Manager::*receiver)(Event *)) {
    dis.addListener(type, std::bind(receiver, this, std::placeholders::_1));
  }

  void test() {
    addListener(42, &Manager::receive);
  }

  Dispatcher dis;
};