Search code examples
c++templatesvariadictype-deduction

Variadic template function parameters and reference type deduction


I'm missing something very fundamental about type deduction here:

I'm attempting to write a wrapper function that calls a writer function with a nullptr to get a required length, then resizes a buffer, then calls the function again, now with the resized buffer, to get the final output. There's a large number of these writer functions, and I want to generalize the call/resize/call pattern into a variadic template function.

However, I'm stuck at trying to pass both a function pointer to a function taking the variadic args, and passing the variadic args, when any parameter in the list is a const reference:

static void val_arg(int)            { }
static void ref_arg(const int&)     { }

template <typename... Args>
static void helper(void (*fun)(Args...), Args... args)
{
    (*fun)(args...);
}

void proxy(const int& arg)
{
    helper(&val_arg, arg);  // Fine
    helper(&ref_arg, arg);  // 'void helper(void (__cdecl *)(Args...),Args...)': template parameter 'Args' is ambiguous
                            // note: could be 'const int&'
                            // note: or       'int'
}

void test()
{
    proxy(1);               // Force 1 to be const int&
}

What can I do to make it transparently accept both cases? Why is it not acknowledging that the function passed in accepts a const ref, and the argument to the proxy is also a const ref?


Solution

  • Args... won't deduce a reference type.

    template <typename Fun, typename... Args>
    static void helper(Fun fun, Args&&... args)
    {
        fun(std::forward<Args>(args)...);
    }