std::bind()
按值接受其参数。这意味着在第一种情况下,您按值传递指针,从而产生指针的副本。在第二种情况下,您foo
按值传递类型对象,从而生成类型对象的副本Foo
。
因此,在第二种情况下,表达式的评估会导致在原始 object的副本上调用L()
成员函数,这可能是也可能不是您想要的。get()
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);