Home > Software design >  Problem converting member function pointer to std::function with CRTP
Problem converting member function pointer to std::function with CRTP

Time:10-13

I am trying to pass a bound member function as an std::function while hiding the std::bind_front invocation in a base class. Minimal example:

#include <functional>

static void runIt(std::function<void()> f) { f(); }

template<typename T>
struct Base {
    using PFn = void (T::*)();
    void run(PFn fun) { runIt(std::bind_front(fun, this)); }
};

struct Derived : Base<Derived> {
    void main() { run(&Derived::func); }
    void func() {}
};

Unfortunately, the compiler does not like it:

static void runIt(std::function<void()> f)
No matching function for call to 'runIt' clang(ovl_no_viable_function_in_call)
test.cpp(12, 19): In instantiation of member function 'Base<Derived>::run' requested here
test.cpp(3, 13): Candidate function not viable: no known conversion from 'std::__perfect_forward_impl<std::__bind_front_op, std::__tuple_types<void (Derived::*)(), Base<Derived> *>, std::__tuple_indices<0, 1>>' to 'std::function<void ()>' for 1st argument

What am I missing?

CodePudding user response:

You can't std::invoke(fun, this) since this is of type Base<Derived>* and the function pointer is of type void (Derived::*)() (And Derived is not a base of Base<Derived>, but the other way around).

Either upcast the pointer to member function or the pointer to the object. Preferably the object pointer:

runIt(std::bind_front(fun, static_cast<T*>(this)));
  • Related