std::bind() takes its arguments by value . This means that in the first case, you pass a pointer by value, resulting in a copy of the pointer. In the second case, you pass an object of type foo by value, resulting in a copy of an object of type Foo .
As a result, in the second case, evaluating the expression L() calls the get() member function for a copy of the original foo object, which may or may not be what you want.
This example illustrates the difference (forget about breaking rule three / rule five, this is just for illustration):
#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 }
Living example .
If for some reason you do not want to use a pointer form, you can use std::ref() to prevent a copy of the argument from being created:
auto L = std::bind(&Foo::get, std::ref(foo), 3);
Andy prowl
source share