c++templatesc++17std-invoke

How can I pass a member function pointer type to a template?


I am trying to delegate a method call using a nested std::invoke. Sample code:

class Executor
{
public:
    bool Execute(bool someFlag);
};

template <class TMemberFunction, class TInstance, typename TResponse>
class Invoker
{
public:
    TResponse Invoke(TMemberFunction* function, TInstance* instance, bool someFlag) {
        return std::invoke(function, instance, someFlag);
    }
};

void Main()
{
    // Create an executor
    Executor executor;
    bool someFlag = true;

    // How can I pass the member function type here?
    Invoker<???, Executor, bool> invoker;
    // Invoke member method
    bool response = invoker.Invoke(&Executor::Execute, &executor, someFlag);
}

What's the proper way to pass the member function's type to the Invoker template?

Edit: sample code corrections.


Solution

  • You might write your Invoker class like:

    template <typename TMemberFunction>
    class Invoker;
    
    template <class C, typename Ret, typename... Args>
    class Invoker<Ret (C::*) (Args...)>
    {
    public:
        Ret Invoke(Ret (C::*method) (Args...), C* instance, Args... args) {
            return std::invoke(method, instance, std::forward<Args>(args)...);
        }
    };
    
    template <class C, typename Ret, typename... Args>
    class Invoker<Ret (C::*) (Args...) const>
    {
    public:
        Ret Invoke(Ret (C::*method) (Args...) const, const C* instance, Args... args) {
            return std::invoke(method, instance, std::forward<Args>(args)...);
        }
    };
    // other specializations to handle combination of volatile, ref, c-ellipsis
    

    and than use it:

    int main()
    {
        Executor executor;
        Invoker <bool (Executor::*)(bool)> invoker;
        bool response = invoker.Invoke(&Executor::Execute, &executor, true);
        // ..
    }