Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 948
Martin Morterol Avatar asked Jun 06 '26 22:06

Martin Morterol


1 Answers

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.

like image 114
NathanOliver Avatar answered Jun 09 '26 10:06

NathanOliver



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!