Std :: bind class member function

I have this code:

#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; } 

It seems that:

 auto L = std::bind(&Foo::get, &foo, 3); 

equivalent to:

 auto L = std::bind(&Foo::get, foo, 3); 

Why?

+11
source share
2 answers

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); 
+19
source

They do not match. The std::bind common function notation copies its arguments. In the case of std::bind(&Foo::get,&foo,3) pointer is copied, but when you call the associated object, it still applies to the original foo object. In std::bind(&Foo::get,foo,3) the foo object is copied, and a later call is applied to the linked copy, and not to the original object.

You can verify this by using a member function that accesses the internal state of the object, binds the object in both directions, changes the original object, and sees how the results differ.

+4
source

All Articles