Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In temp.deduct.partial, why is a parameter pack less specialized?

In temp.deduct.partial#8, there's an example:

template<class... Args>           void f(Args... args);         // #1
template<class T1, class... Args> void f(T1 a1, Args... args);  // #2
template<class T1, class T2>      void f(T1 a1, T2 a2);         // #3

f();                // calls #1
f(1, 2, 3);         // calls #2
f(1, 2);            // calls #3; non-variadic template #3 is more specialized
                    // than the variadic templates #1 and #2

Call #1 is trivial, since there's only one viable specialization.

For call #2, f₁ and f₂ are viable. We synthesize f₁(X) and f₂(X, Y). We then do type deduction both ways.

First f₂(X, Y) against f₁(Args... args), which deduces Args to be X, Y.

Then f₁(X) against void f₂(T1 a1, Args... args), which deduces T1 as X, and Args as empty.

So deduction succeeds in both ways, and neither is more specialized than the other.

Could we be saved by temp.deduct.partial#11?

If, after considering the above, function template F is at least as specialized as function template G and vice-versa, and if G has a trailing parameter pack for which F does not have a corresponding parameter, and if F does not have a trailing parameter pack, then F is more specialized than G.

Doesn't look like this helps. Let F=f₁, G=f₂, then G does indeed have a trailing parameter pack for which F does not have a corresponding parameter. But F has a trailing parameter pack, so this does not apply.

Did I misread anything in the standard, or is the answer maybe found somewhere else entirely?

like image 439
knatten Avatar asked Mar 04 '19 09:03

knatten


1 Answers

This was answered by Simon Brand on Twitter. The key is in temp.deduct#type-10.2:

During partial ordering, if Ai was originally a function parameter pack: (...) if Pi is not a function parameter pack, template argument deduction fails.

In this case, when doing f₁(X) against f₂(T1 a1, Args... args), X was originally a function parameter pack. T1 is however not a function parameter pack, so deduction fails.

Since we can deduce f₁ from f₂, but not the other way around, f₂ is more specialized.

like image 104
knatten Avatar answered Oct 31 '22 19:10

knatten