鉴于以下内容,"功能"?
#include <functional>
#include <vector>
template<class T>
class Foo
{
public:
template<typename P, typename Q, typename R, typename... Args>
void Attach(P (Q::*f)(Args...), R p)
{
auto function = [p, f](Args... args)
{
(*p.*f)(args...);
};
Listeners.push_back(function);
}
private:
std::vector<std::function<T>> Listeners;
};
class Bar
{
public:
int Handler(int x, int y, int z)
{
return 0;
}
};
int main(void)
{
auto foo = Foo<int(int, int, int)>();
auto bar = Bar();
foo.Attach(&Bar::Handler, &bar);
}
对于某些上下文,我尝试创建一个调用实例上方法的lambda,将该lambda存储到集合中。我的push_back无法编译,出现以下错误:
xrefwrap(283):错误C2440:&#39;返回&#39; :无法转换为&#39; void&#39;至 &#39; INT&#39;
我最初使用std :: bind来创建一个我可以存储的std :: function。显然我可以用lambda(和可变参数模板,所以我不需要每个模板一个模板),但到目前为止,它击败了我。
答案 0 :(得分:6)
构建Foo
后,提供的显式模板参数为auto foo = Foo<int(int, int, int)>();
,
int main(void)
{
auto foo = Foo<int(int, int, int)>(); //<<<< Here is the template arguments when constructing Foo
auto bar = Bar();
foo.Attach(&Bar::Handler, &bar);
}
当您注册监听器时,函数签名返回类型为void
auto function = [p, f](Args... args)
{
(*p.*f)(args...);
};
所以要么你
auto foo = Foo<void(int, int, int)>();
返回void以匹配您的侦听器回调。return (*p.*f)(args...);
注意您可能打算从侦听器返回状态代码,但您可能错过了?所以第二个解决方案点在我看来是一个明显合理的问题