Using generic std::function objects with member functions in one class
A non-static member function must be called with an object. That is, it always implicitly passes "this" pointer as its argument.
Because your std::function
signature specifies that your function doesn't take any arguments (<void(void)>
), you must bind the first (and the only) argument.
std::function<void(void)> f = std::bind(&Foo::doSomething, this);
If you want to bind a function with parameters, you need to specify placeholders:
using namespace std::placeholders;
std::function<void(int,int)> f = std::bind(&Foo::doSomethingArgs, this, std::placeholders::_1, std::placeholders::_2);
Or, if your compiler supports C++11 lambdas:
std::function<void(int,int)> f = [=](int a, int b) {
this->doSomethingArgs(a, b);
}
(I don't have a C++11 capable compiler at hand right now, so I can't check this one.)
Either you need
std::function<void(Foo*)> f = &Foo::doSomething;
so that you can call it on any instance, or you need to bind a specific instance, for example this
std::function<void(void)> f = std::bind(&Foo::doSomething, this);
If you need to store a member function without the class instance, you can do something like this:
class MyClass
{
public:
void MemberFunc(int value)
{
//do something
}
};
// Store member function binding
auto callable = std::mem_fn(&MyClass::MemberFunc);
// Call with late supplied 'this'
MyClass myInst;
callable(&myInst, 123);
What would the storage type look like without auto? Something like this:
std::_Mem_fn_wrap<void,void (__cdecl TestA::*)(int),TestA,int> callable
You can also pass this function storage to a standard function binding
std::function<void(int)> binding = std::bind(callable, &testA, std::placeholders::_1);
binding(123); // Call
Past and future notes: An older interface std::mem_func existed, but has since been deprecated. A proposal exists, post C++17, to make pointer to member functions callable. This would be most welcome.