简体   繁体   English

没有可行的重载'='来分配std :: function回调作为成员函数

[英]No viable overloaded '=' for assigning std::function callback as member function

I'm trying to hook a member function up to an std::function callback. 我试图将成员函数挂钩到std::function回调。 The callback type is: 回调类型为:

std::function<void(Touch*, Event*)>

My member function is: 我的成员函数是:

void Game::onTouchEnded(Touch* touch, Event* event)

When I try to assign the callback using the following: 当我尝试使用以下方法分配回调时:

listener->onTouchEnded = bind(&Game::onTouchEnded, this);

I get a No viable overloaded '=' error with several candidates. 我收到几个候选No viable overloaded '='错误提示,其中No viable overloaded '='错误。 Here are the details of the one I believe to be most relevant: 以下是我认为最相关的详细信息:

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`

I've tried several different bind() arrangements but I'm not sure what the error is telling me. 我尝试了几种不同的bind()安排,但不确定该错误告诉我什么。 The types all seem to be correct in terms of the parameters and return value so I'm not sure why it won't accept it? 在参数和返回值方面,所有类型似乎都是正确的,因此我不确定为什么它不接受它?

Try 尝试

listener->onTouchEnded = bind(&Game::onTouchEnded, this, std::placeholders::_1, std::placeholders::_2);

or try a lambda function 或尝试使用lambda函数

listener->onTouchEnded = [this](Touch* touch, Event* event){ this->onTouchEnded(touch, event); };

bind must be told what to do with parameters passed to its return value. 必须告知bind如何处理传递给其返回值的参数。 By default, it simply discards them. 默认情况下,它只是丢弃它们。

When you pass it to the std::function , it tries to type-erase it. 当您将其传递给std::function ,它将尝试对它进行类型擦除。 std::function passes a Touch*, Event* to the bind . std::functionTouch*, Event*传递给bind bind 's return value discards them, and calls (this->*&Game::onTouchEnded)() , as you requested. bind的返回值将其丢弃,并根据您的要求调用(this->*&Game::onTouchEnded)() This is not a valid call, and you get an error. 这不是有效的电话,您会收到错误消息。

The simple way to fix this is to add placeholders that say "what do do with arguments to the bind return value". 解决此问题的简单方法是添加占位符,该占位符应说明“对绑定返回值的参数做什么”。 bind treats member functions as functions that take an extra this argument first. bind将成员函数视为首先需要额外接受this参数的函数。 You want: 你要:

(this->*&Game::onTouchEnded)(_1, _2)

which corresponds to: 对应于:

std::bind(&Game::onTouchEnded, this, _1, _2)

Now this is all well and good, but really you should avoid std::bind . 现在一切都很好,但实际上您应该避免std::bind Fully understanding it is tricky: It has strange corner cases that can bite you, or force you to needlessly type-erase, when you call it recursively. 完全理解它是棘手的:当您递归调用它时,它的奇怪案例可能会咬住您,或迫使您不必要地键入-擦除。

Instead, use a lambda. 而是使用lambda。 In C++11 it looks like: 在C ++ 11中,它看起来像:

[this](Touch* touch, Event* event){return this->onTouchEnded(touch, event);}

In C++14, an alternative is: 在C ++ 14中,替代方法是:

[this](auto&&args)->decltype(auto){return this->onTouchEnded(decltype(args)(args)...);}

or even: 甚至:

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

which can be used like this: 可以这样使用:

bind_method(this, &Game::onTouchEnded)

and is a drop-in replacement to your call to bind . 并且是您对bind的调用的直接替代。 Here, we auto-forward the arguments to the method we call, instead of having to list them explicitly. 在这里,我们将参数自动转发给调用的方法,而不必显式列出它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM