Home > Software engineering >  Pass member function as function pointer to argument
Pass member function as function pointer to argument

Time:12-07

Here is my Code:
I want to use a class inside my custom MyStateMachine. I do not want to inherit de StateMachine class as I just want to use it with its functions. The MyStateMachine class is only to encapsulate a few things.

MyStateMachine.h

#include <StateMachine.h>

class MyStateMachine {
 public:
    void Initialisation();

 private:
    StateMachine machine = StateMachine();
    State* m0Initialisation = machine.addState(&Initialisation); // problem here
};

MyStateMachine.cpp

#include "MyStateMachine.h"

void MyStateMachine::Initialisation() {
   // do initialisation stuff here
}

machine.addState expects a function pointer as argument: State* addState(void (*functionPointer)());

I get the following error message:

error: no matching function for call to 'StateMachine::addState(void (MyStateMachine::*)())
note: State* StateMachine::addState(void (*)())
     State* addState(void (*functionPointer)());
note:   no known conversion for argument 1 from 'void (MyStateMachine::*)()' to 'void (*)()'
Compilation error: no matching function for call to 'StateMachine::addState(void (MyStateMachine::*)())'

If I define the function outside the class, I can successfully pass this function as a function pointer (&Initialization). I guess it has something to do that it is a function of a class and it needs the reference to the object. But even with that I did not find a solution.

How could I pass the function? If possible without external libraries (e.g. std::bind).

I have looked at a few posts but could not find a proper solution.

CodePudding user response:

There is some different solutions to your problem.

1: Change the type of your funciton pointer in Statemachine::addState(...) to be a function pointer to a member type instead of a function pointer to a non member function.

Check out section "Pointers to members" here

2: Use std::function as the type of addState and do

State* m0Initialisation = machine.addState([this]() {Initialisation(); });

3: Change Initialization to be static and send in a pointer to your class every time you call the function.

static void Initialisation(StateMachine &self);

CodePudding user response:

The problem is that StateMachine::addState expects a normal function pointer, which is different from a member function pointer. You can make your Initialization function static. Then the member function pointer is essentially a normal function pointer:

struct State {};

struct StateMachine {
    State* addState (void (*)()){ return nullptr; }
};

class MyStateMachine {
 public:
    static void Initialisation();

 private:
    StateMachine machine = StateMachine();
    State* m0Initialisation = machine.addState(&Initialisation); // no problem here
};

Member functions always have an implicit first argument, which is a pointer or reference to an instance of the class. This is the main difference between a normal function pointer and a member function pointer. So taking the implicit argument into account, the member function is not a void nullary function with signature `void (*)(). Static member functions do not have an implicit first argument, so member function pointers to static member functions can be treated like normal function pointers.

  • Related