std::function
is perfectly capable of storing a member function pointer directly. However, you have to adjust the argument list appropriately. Member pointers must be called with an instance of the type (or a derived type). When putting them in a std::function
, the first argument in the argument list is expected to be a pointer (or reference or smart-pointer) to the object type.
So, if I have the following class:
struct Type
{
public:
int Foo();
};
The correct syntax to store this member function in a std::function
is:
std::function<int(Type&)> fooCaller = &Type::Foo;
If you want to preserve the argument list (in your case, int(double)
), then you need to provide the instance outside of the function
. This can be done via std::bind
:
struct A{ int fn(double){ return 0; } };
A anInstance;
std::function<int(double)> fnCaller = std::bind(&A::fn, &anInstance, std::placeholders::_1);
Note that it is your responsibility to ensure that the object pointer you provide to std::bind
remains alive so long as fnCaller
is alive. If you return fnCaller
to someone, and it has a pointer to a stack object, you're in trouble.
What's nice is that you could bind a shared_ptr
(or any copyable smart pointer) as your object, thanks to how the function call mechanism is defined:
struct A{ int fn(double){ return 0; } };
auto anInstance = std::make_shared<A>();
std::function<int(double)> fnCaller = std::bind(&A::fn, anInstance, std::placeholders::_1);
Now you don't have to worry; the binder will continue to keep the object alive, since it stores a shared_ptr
by value.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…