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)));