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.
- pass-an-objects-member-function-as-argument-function-pointer
- class-member-function-as-function-pointer
- using-pointers-to-member-to-pass-member-function-as-arguments
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.