dan*_*jar 19 c++ member-functions c++11 std-function
我可以轻松地将成员函数绑定到a std::function带有capture子句的lambda表达式.
class Class
{
Class()
{
Register([=](int n){ Function(n); });
}
void Register(std::function<void(int)> Callback)
{
}
void Function(int Number)
{
}
};
Run Code Online (Sandbox Code Playgroud)
但我想直接绑定它们,如下所示.
// ...
Register(&Class::Function);
// ...
Run Code Online (Sandbox Code Playgroud)
我认为根据C++ 11标准,这应该得到支持.但是,在Visual Studio 11中,我收到了这些编译器错误.
错误C2440:'换行':无法从'int'转换为'Class*'
错误C2647:'.*':无法在'int'上取消引用'void(__thiscall Class ::*)(int)'
jua*_*nza 36
我认为根据C++ 11标准,这应该得到支持
不是真的,因为非静态成员函数具有隐式的第一个类型参数(cv-qualified)YourType*,所以在这种情况下它不匹配void(int).因此需要std::bind:
Register(std::bind(&Class::Function, PointerToSomeInstanceOfClass, _1));
Run Code Online (Sandbox Code Playgroud)
例如
Class c;
using namespace std::placeholders; // for _1, _2 etc.
c.Register(std::bind(&Class::Function, &c, _1));
Run Code Online (Sandbox Code Playgroud)
编辑您提到要使用相同的Class实例调用它.在这种情况下,您可以使用简单的非成员函数:
void foo(int n)
{
theClassInstance.Function(n);
}
Run Code Online (Sandbox Code Playgroud)
然后
Class c;
c.Register(foo);
Run Code Online (Sandbox Code Playgroud)
And*_*ndy 31
根据Stephan T. Lavavej - "避免使用bind(),...,使用lambdas". https://www.youtube.com/watch?v=zt7ThwVfap0&t=32m20s
在这种情况下:
Class()
{
Register([this](int n){ Function(n); });
}
Run Code Online (Sandbox Code Playgroud)
你可以使用std::bind:
using namespace std::placeholders; // For _1 in the bind call
// ...
Register(std::bind(&Class::Function, this, _1));
Run Code Online (Sandbox Code Playgroud)
在 C++ 17 中,您可以使用:
Register([=](auto && ...args){ return Function(args...); });
Run Code Online (Sandbox Code Playgroud)
这很不错,尤其是当参数列表较长时。当然,成员函数的参数列表必须与 的参数std::function列表兼容。