我有这个代码:
#include <iostream>
#include <functional>
struct Foo
{
int get(int n) { return 5+n; }
};
int main()
{
Foo foo;
auto L = std::bind(&Foo::get, &foo, 3);
std::cout << L() << std::endl;
return 0;
}
似乎是这样的:
auto L = std::bind(&Foo::get, &foo, 3);
相当于:
auto L = std::bind(&Foo::get, foo, 3);
为什么?
最佳答案
std::bind()
按值 接受其参数。这意味着在第一种情况下,您将按值传递一个指针,从而得到一个指针的拷贝。在第二种情况下,您按值传递类型为 foo
的对象,从而生成类型为 Foo
的对象的拷贝。
因此,在第二种情况下,表达式 L()
的求值导致成员函数 get()
在 copy 的原始对象 foo
,它可能是也可能不是你想要的。
这个例子说明了区别(忘记违反三规则/五规则,这只是为了说明目的):
#include <iostream>
#include <functional>
struct Foo
{
int _x;
Foo(int x) : _x(x) { }
Foo(Foo const& f) : _x(f._x)
{
std::cout << "Foo(Foo const&)" << std::endl;
}
int get(int n) { return _x + n; }
};
int main()
{
Foo foo1(42);
std::cout << "=== FIRST CALL ===" << std::endl;
auto L1 = std::bind(&Foo::get, foo1, 3);
foo1._x = 1729;
std::cout << L1() << std::endl; // Prints 45
Foo foo2(42);
std::cout << "=== SECOND CALL ===" << std::endl;
auto L2 = std::bind(&Foo::get, &foo2, 3);
foo2._x = 1729;
std::cout << L2() << std::endl; // Prints 1732
}
如果出于任何原因不想使用指针形式,可以使用 std::ref()
防止创建参数的拷贝:
auto L = std::bind(&Foo::get, std::ref(foo), 3);
关于c++ - std::bind 类成员函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16016112/