c++ - 如何将函数指针传递给绑定?
问题描述
我有以下代码:
_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){
....
}
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 *)>'
解决方案
第一个错误是因为您正在获取函数指针的地址。因此,您将一个指向函数的指针传递给std::bind
.
第二个错误是因为您使用了 avoid *
并且以某种方式期望它可以工作!
试试这个 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;
};
推荐阅读
- string - 用多个空格分割字符串
- vb.net - 在 vb.net 中通过 http 上传到虚拟目录时遇到麻烦
- xcode - 在反应本机插件中找不到xcode库文件的标头
- c# - 如何从存储过程中获取 Table 结果?
- dart - 在颤动中使用png裁剪图像?
- wordpress - 如何获得运输类别名称而不是 woocommerce
- c# - Directory.CreateDirectory() 返回“对路径 '..\\[folder]\\' 的访问被拒绝。” 与 SpecFlow 测试一起使用时出现异常
- selenium-webdriver - 在我检查页面之前,Selenium 找不到元素
- rabbitmq - MassTransit 请求响应示例
- reactjs - Azure 应用服务身份验证 - 尝试获取 /.auth/me 时出现 302