Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to directly bind a member function to an std::function in Visual Studio 11?

I can easily bind member functions to a std::function by wrapping them with a lambda expression with capture clause.

class Class {     Class()     {         Register([=](int n){ Function(n); });     }      void Register(std::function<void(int)> Callback)     {      }      void Function(int Number)     {      } }; 

But I want to bind them directly, something like the following.

// ... Register(&Class::Function); // ... 

I think according to the C++11 standard, this should be supported. However, in Visual Studio 11 I get these compiler errors.

error C2440: 'newline' : cannot convert from 'int' to 'Class *'

error C2647: '.*' : cannot dereference a 'void (__thiscall Class::* )(int)' on a 'int'

like image 602
danijar Avatar asked Jun 16 '13 09:06

danijar


People also ask

What does std :: bind do in C++?

std::bind is a Standard Function Objects that acts as a Functional Adaptor i.e. it takes a function as input and returns a new function Object as an output with with one or more of the arguments of passed function bound or rearranged.

How does STD bind work?

std::bind allows you to create a std::function object that acts as a wrapper for the target function (or Callable object). std::bind also allows you to keep specific arguments at fixed values while leaving other arguments variable.

What is boost bind?

boost::bind is a generalization of the standard functions std::bind1st and std::bind2nd. It supports arbitrary function objects, functions, function pointers, and member function pointers, and is able to bind any argument to a specific value or route input arguments into arbitrary positions.


2 Answers

I think according to the C++11 standard, this should be supported

Not really, because a non-static member function has an implicit first parameter of type (cv-qualified) YourType*, so in this case it does not match void(int). Hence the need for std::bind:

Register(std::bind(&Class::Function, PointerToSomeInstanceOfClass, _1)); 

For example

Class c; using namespace std::placeholders; // for _1, _2 etc. c.Register(std::bind(&Class::Function, &c, _1)); 

Edit You mention that this is to be called with the same Class instance. In that case, you can use a simple non-member function:

void foo(int n) {   theClassInstance.Function(n); } 

then

Class c; c.Register(foo); 
like image 142
juanchopanza Avatar answered Sep 25 '22 21:09

juanchopanza


According to Stephan T. Lavavej - "Avoid using bind(), ..., use lambdas". https://www.youtube.com/watch?v=zt7ThwVfap0&t=32m20s

In this case:

Class() {     Register([this](int n){ Function(n); }); } 
like image 20
Andy Avatar answered Sep 24 '22 21:09

Andy