jf192210
jf192210

Reputation: 157

Obtaining a function pointer to a non static member function

Suppose I have a class:

class A {
public:
    A(); 
    void myFunc();
};

Then at a different point in the program I create an instance of class A, and attempt to obtain a function pointer to myFunc():

A* a = new A;

//ATTEMPTS AT RETRIVING FUNCTION POINTER FOR A::MYFUNC

std::function<void()> fnptr = a->myFunc;

std::function<void()> fnptr(std::bind(A::myFunc, &a);

But both of these attempts present the error "call to non static member function without object argument"

Perhaps both of these attempts are totally off the mark, but essentially im trying to obtain a function pointer to the myFunc() function in the specific instance of a. Any help on how to do so is appreciated :)

Upvotes: 3

Views: 1152

Answers (2)

jfMR
jfMR

Reputation: 24738

I'm trying to obtain a function pointer to the myFunc() function

Obtaining a pointer to member function for A::myFunc() can be done:

void (A::*memFuncPtr)() = &A::myFunc;

or even better, taking advantage of auto:

auto memFuncPtr = &A::myFunc;

However, to dereference this pointer (i.e., to call the member function it points to), you will eventually need an A object. This object corresponds to the one the member function will be called on.

You can dereference the pointer to member function, memFuncPtr, either in combination with an A object and the .* operator:

A a;
a.*memFuncPtr();

or in combination with a pointer to an A object and the operator ->*:

A *aPtr = new A();
aPtr->*memFuncPtr();

As a result, you would need to keep a reference to the object or a copy of it in order to create std::function<void()> out of this pointer to member function.

std::invoke

Since C++17, you can simply use the std::invoke() function template instead of .* / ->*. It unifies the syntax for the two cases exposed above:

std::invoke(memFuncPtr, a);
std::invoke(memFuncPtr, aPtr);

Upvotes: 3

cigien
cigien

Reputation: 60228

You need the following syntax:

std::function<void()> fnptr(std::bind(&A::myFunc, a));

You could also use a lambda expression like this:

auto fn = [a] { a->myFunc(); };

Here's a demo.

Upvotes: 2

Related Questions