Search code examples
c++delegatesvariadic-templatessignatureoverload-resolution

How do I resolve an overloaded function by it's signature as a template parameter?


I'm writing a delegate library and stubled upon this problem: Let's say I have overloaded functions named foo like this:

int foo(double d);
double foo(int d);

How would I write my template argument list if I want to resolve which function is meant by specifying a signature as a template parameter. I basically want this syntax (yet it shall work with any signature):

Delegate d = make_delegate<&foo,int(double)>(); // "Delegate" is automatically deduced as Delegate<int(double)>

I managed to resolve it by using the following helper template, but it only works if I write the parameter types of the function signature manually. I struggle to forward the variadic parameter pack Args... (which is encoded in the Args_pack specialization) to the function signature.

template<typename... Args>
struct Args_pack {}

template<typename Signature>
struct Identify_signature_type;

template<typename Return, typename... Args>
struct Identify_signature_type<Return(Args...)> {

    using T_return = Return;
    using Args_pack = Args_pack<Args...>;
};

template<auto Signature> using Identify_signature = Identify_signature_type<decltype(Signature)>;


template<typename Signature, typename Identify_signature_type<Signature>::T_return Function(double /* important magic needed here */)>
auto make_delegate()
{...}

Delegate d = make_delegate<int(double), &foo>(); // Works. However, it would be nice if the template parameters could exchange places.

Solution

  • You can add a * to the signature to get the right function pointer type.

    template<typename Signature, Signature* fptr>
    auto make_delegate()
    {...}