0

If you have a pointer to a member function like so:

struct Foo {  void func() {}  };

void(Foo::*funcPtr)() = &Foo::func;

Is there a way to get the type of the function, with the Foo:: removed?

I.e.,

void(Foo::*)() -> void(*)()

int(Foo::*)(int, double, float) -> int(*)(int, double, float)

You get the idea.

The goal is to make std::function accept a functor like this:

struct Functor { void operator()(...){} }

Functor f;
std::function< magic_get_function_type< decltype(Functor::operator()) >::type > stdfunc{f};

Is it possible?

JensB
  • 839
  • 4
  • 19
  • 4
    FWIW, If you have C++17 you should just be able to do `auto stdfunc = std::function{Functor{}};` – NathanOliver Dec 13 '21 at 20:59
  • Related-ish: https://stackoverflow.com/a/28509563/4641116 – Eljay Dec 13 '21 at 21:04
  • You can also use lambdas: `std::function f = []() { /*do stuff*/ };` – Offtkp Dec 13 '21 at 21:11
  • @NathanOliver Wow. I had somehow gotten the idea that `std::function` cannot deduce its template arguments, and I have as a result been trying to solve non-existent problems for the past week. My past four questions on SO (one of which you answered) have all revolved around this. Feeling a bit silly now. – JensB Dec 13 '21 at 21:23
  • @JensB Don't feel too bad. This was a feature that was added to C++ starting with C++17. For more reading on it, lookup Class Template Argument Deduction (CTAD) – NathanOliver Dec 13 '21 at 21:24

1 Answers1

0

To answer your question, it is possible with a simple template:

template <typename Return, typename Class, typename... Args>
Return(*GetSig(Return(Class::*)(Args...)))(Args...);

This defines a function called GetSig that takes as parameter a member function pointer and essentially extracts the Return type and the Args... and returns it as a non-member function pointer.

Example usage:

class C;
int main() {
    using FuncType = int(C::*)(double, float);
    FuncType member_pointer;
    decltype(GetSigType(member_pointer)) new_pointer;
    // new_pointer is now of type int(*)(double, float) instead of
    // int(C::*)(double, float)
}
Offtkp
  • 366
  • 2
  • 9