没有可行的重载'='用于将std :: function回调赋值为成员函数
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了没有可行的重载'='用于将std :: function回调赋值为成员函数相关的知识,希望对你有一定的参考价值。
我正在尝试将成员函数挂钩到std::function
回调。回调类型是:
std::function<void(Touch*, Event*)>
我的会员职能是:
void Game::onTouchEnded(Touch* touch, Event* event)
当我尝试使用以下内容分配回调时:
listener->onTouchEnded = bind(&Game::onTouchEnded, this);
我和几个候选人一起得到了No viable overloaded '='
错误。以下是我认为最相关的细节:
Candidate function not viable: no known conversion from
'__bind<void (Game::*)(cocos2d::Touch *, cocos2d::Event *), Game *>'
to
'std::__1::function<void (cocos2d::Touch *, cocos2d::Event *)>'
for 1st argument`
我尝试了几种不同的bind()安排,但我不确定错误告诉我的是什么。所有类型在参数和返回值方面似乎都是正确的,所以我不确定它为什么不接受它?
尝试
listener->onTouchEnded = bind(&Game::onTouchEnded, this, std::placeholders::_1, std::placeholders::_2);
或尝试lambda函数
listener->onTouchEnded = [this](Touch* touch, Event* event){ this->onTouchEnded(touch, event); };
必须告诉bind
如何处理传递给其返回值的参数。默认情况下,它只是丢弃它们。
当你将它传递给std::function
时,它会尝试键入 - 擦除它。 std::function
将Touch*, Event*
传递给bind
。 bind
的返回值丢弃它们,并按照您的要求调用(this->*&Game::onTouchEnded)()
。这不是一个有效的调用,并且您收到错误。
解决这个问题的简单方法是添加占位符,说明“如何处理绑定返回值的参数”。 bind
将成员函数视为首先采用额外this
参数的函数。你要:
(this->*&Game::onTouchEnded)(_1, _2)
对应于:
std::bind(&Game::onTouchEnded, this, _1, _2)
现在这一切都很好,但实际上你应该避免使用std::bind
。完全理解它是很棘手的:当你递归地调用它时,它有一些奇怪的角落情况可以咬你,或强迫你不必要地进行类型擦除。
相反,使用lambda。在C ++ 11中,它看起来像:
[this](Touch* touch, Event* event){return this->onTouchEnded(touch, event);}
在C ++ 14中,另一种选择是:
[this](auto&&args)->decltype(auto){return this->onTouchEnded(decltype(args)(args)...);}
甚至:
template<class T, class M>
auto bind_method( T* t, M* m ) {
return [t, m](auto&&...args)->decltype(auto){
return (t->*m)(decltype(args)(args)...);
};
}
可以像这样使用:
bind_method(this, &Game::onTouchEnded)
并且是您拨打bind
的替代品。在这里,我们将参数自动转发给我们调用的方法,而不必显式列出它们。
以上是关于没有可行的重载'='用于将std :: function回调赋值为成员函数的主要内容,如果未能解决你的问题,请参考以下文章
'mysql'没有重载匹配委托'ElapsedEventHandler'。 Windows服务C#