2

I have a slightly convoluted use case of passing a member function pointer to an outside function which is then called again by a member function (Don't ask!). I'm learning about std::function and std::mem_fn but I can't seem to be able to convert my old school function pointer

void (T::*func)(int) to a std::function<void (T::*)(int) func>

in the code below, I'd like to be able to pass a std::function to memFuncTaker in the call from anotherMember

#include "class2.hpp" 
#include <iostream> 

class outer{ 
public: 
  void aMember(int a){ 
    std::cout << a <<std::endl; 
  } 
  void anotherMember(double){ 
    memFuncTaker(this, &outer::aMember); 
  } 

}; 


template<class T> 
void memFuncTaker(T* obj , void (T::*func)(int) ){ 
  (obj->*func)(7); 
} 
2
  • 6
    I don't see any attempts to use std::function in your code. Commented Nov 1, 2017 at 3:13
  • Your question title says "Converting pointer to member function to std::function", but the question sounds like "Converting std::function to pointer to member function". Commented Nov 1, 2017 at 8:16

1 Answer 1

2

When you bind std::function to a non-static member function pointer, it "reveals" the hidden this parameter, making it the first explicit parameter of the resultant functor. So in your case for outer::aMember you'd use std::function<void(outer *, int)> and end up with a two-parameter functor

#include <functional>
#include <iostream> 

template<class T> 
void memFuncTaker(T *obj , std::function<void(T *, int)> func){ 
  func(obj, 7);
} 

class outer{ 
public: 
  void aMember(int a){ 
    std::cout << a <<std::endl; 
  } 
  void anotherMember(double){ 
    memFuncTaker(this, std::function<void(outer *, int)>{&outer::aMember}); 
  } 
}; 

int main() {
  outer o;
  o.anotherMember(0);
}

http://coliru.stacked-crooked.com/a/5e9d2486c4c45138

Of course, if you prefer, you can bind the first argument of that functor (by using std::bind or lambda) and thus "hide" it again

#include <functional>
#include <iostream> 

using namespace std::placeholders;

void memFuncTaker(std::function<void(int)> func){ 
  func(7);
} 

class outer{ 
public: 
  void aMember(int a){ 
    std::cout << a <<std::endl; 
  } 
  void anotherMember(double){ 
    memFuncTaker(std::function<void(int)>(std::bind(&outer::aMember, this, _1))); 
  } 
}; 

int main() {
  outer o;
  o.anotherMember(0);
}

Note that in this version memFuncTaker no longer has to be a template (which happens to be one of the primary purposes of std::function - employ type erasure techniques to "de-templatize" the code).

Sign up to request clarification or add additional context in comments.

3 Comments

How come the return type of std::bind(&outer::aMember, this, _1) is std::function<void(int)>. I know aMember is a member function but how come this doesn't show up the function signature bound to std::function. I expected std::bind(&outer::aMember, this, _1) to return std::function<void(outer*, int)>
@creationist: Why? The whole purpose of that std::bind is to eliminate (bind) the first (outer *) parameter. Before std::bind the functor had two parameters - outer * and int, - but after std::bind only one was left: int.
For another example, if you do std::mem_fn(&outer::aMember) you will get a two-parameter functior (just like you described). But if after that you do std::bind(std::mem_fn(&outer::aMember), this, _1) only one parameter will be left. What you see in my answer above is the same thing, since std::mem_fn is optional in this context and can be omitted. std::bind is smart enough to realize what is meant without explicit application of std::mem_fn.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.