0

I'm having problems casting a function pointer. It works (no cast needed) outside a class.

Here is the signature of the function I'm calling.

Result* FancyClass::callMe(void(*functionPointer)())

It works with.

void defaultState()
{
    //
}

// ..

Result *result= instance.callMe(defaultState);

But it does not work with

void MyClass::defaultState()
{
    //
}

// ..
Result *result= instance.callMe(MyClass::defaultState);

I am getting this:

argument of type "void (MyClass::)()" is incompatible with parameter of type "void ()()"

How to cast this correctly?

dknaack
  • 60,192
  • 27
  • 155
  • 202
  • Pointer to member functions are not actually pointers. – Jason Jun 09 '22 at 13:59
  • functions inside a class have implicit hidden argument `this`. Only static method can be cast this way. – Marek R Jun 09 '22 at 13:59
  • The problem it that calling an object finction needs 'this' to be passed, so the signature does not match. Maybe making your object function static can help, but would need more details on what you are trying to achieve – OznOg Jun 09 '22 at 13:59
  • If `callMe` is a library function that you have no control over, then with that signature it is impossible to call it properly with a non-static data member function. That's simply a design flaw of the library. Even as a C-style interface it must accept an additional user context pointer in order to support member function calls. The only thing you can do is call the non-static member function on a static instance of the class via a free function (or static member function). – user17732522 Jun 09 '22 at 14:15

1 Answers1

2

You can't cast it correctly, because pointers to member functions are different from pointers to regular functions. For starters, you must write &MyClass::defaultState, and the parameter has to be of type void(*MyClass::functionPointer)()

You can't even store &MyClass::defaultState directly in a std::function<void()>. What object would you call it on? But you could bind an instance, and store the bound result in a std::function<void()>.

The question was tagged "C", but C doesn't understand classes and can't call member functions.

MSalters
  • 173,980
  • 10
  • 155
  • 350
  • Thank you very much! I am obviously not good at c++. I am doing a little project on the arduino. I am using a 3rd party library and can do this in the main.cpp. But now i want to refactor some functionalitiy which requires me to use the library in the class. – dknaack Jun 09 '22 at 14:04
  • @dknaack: Do you really have a `void(*)(void)` signature? Because that makes things significantly harder. You'd need to somehow pack `this` in existing arguments. Quite a few C interfaces use `void(*)(void*)` - note, that's a `void*` pointer argument. – MSalters Jun 09 '22 at 14:13
  • @MSalters yes. The argument is `void(*functionPointer)()` – dknaack Jun 09 '22 at 14:18