c++variadic-templates

Why does the variadic template function behave differently from the template function?


template<class... T> struct Strct
{
    Strct(double){};
};
    
template<class... T> void foo(Strct<T...>) {}
template<class  T>   void foo2(Strct<T>) {}
foo<double>(1.); // error: no matching function for call to 'foo<double>(double)'
foo2<double>(1.); // Ok 

Demo

Since I give the full list of the template's parameters, the compiler shouldn't have anything to deduce, and both calls should be equivalent to:

void foo2(Strct<double>) {}

Why does the variadic template function behave differently from the template function?

Maybe it is close to why would type_identity make a difference? but I didn't find anything in the related documentation.


Solution

  • I don't understand why there is a difference. In my mind, since I give the full list of the templates parameters, ...

    The issue is that variadic templates like

    template<class... T> void foo(Strct<T...>) {}
    

    have 0 to N template parameters. When you do

    foo<double>(1.);
    

    the first parameter of the parameter pack becomes double, but it is going to try and determine the rest of the parameter pack be deducing what T... is from the parameter. Since a double is not a Strct<T...> that deduction fails.

    You would need

    foo<double>(Strct<double>{1.});
    // or even simpler
    foo(Strct<double>{1.});
    

    to get the first example to compile.