Home > Software design >  Method pointer and constness
Method pointer and constness

Time:10-08

Consider the following hypothetical example:

template<typename T, typename R, typename... Ps>
R call(T& t, R (T::*method)(Ps...), Ps... ps){
    return (t.*method)(ps...);
}

struct A{
    int f(int i) const {return i;}
};
A a;

Then call(a, &A::f, 3) wont compile, because f is const. Can I make call work without providing the following overload:

template<typename T, typename R, typename... Ps>
R call(T& t, R (T::*method)(Ps...) const, Ps... ps){
    return (t.*method)(ps...);
}

CodePudding user response:

There is already a standard library function that allows calling any callable, including member function pointers. You can simply use that for your wrapper function and it will automatically allow using any kind of callable as well:

With C 20:

decltype(auto) call(auto&& f, auto&&... args) {
    /* do whatever you want here */
    return std::invoke(decltype(f)(f), decltype(args)(args)...);
}

This would be passed the member function pointer as first argument, the class object as second argument and the member function arguments after that.

If you need access to the class object you can split this out and use the member function pointer call syntax specifically:

decltype(auto) call(auto&& f, auto&& t, auto&&... args)
{
    /* do whatever you want with t here */
    return (decltype(f)(f).*decltype(t)(t))(decltype(args)(args)...);
}
  • Related