I know the title does no make much of a sense, but the code will explain my problem.
template<typename T>
void foo(T...) {std::cout << 'A';}
template<typename... Ts>
void foo(Ts...) {std::cout << 'B';}
int main(){
foo(1);
foo(1,2);
}
Try to guess the output of this program before reading the continuation:
So the output is AB
Can anyone explain why for 1 argument function the priority is given to ellipsis, and for 2 argument to variadic template?
Per [dcl.fct]
Where syntactically correct and where “...” is not part of an abstract-declarator, “, ...” is synonymous with “...”.
So this makes the first overload a variadic function (that also happens to be templated) that is equivalent to:
template<typename T>
void foo(T, ...) {std::cout << 'A';}
(N.B. The cppreference page contains an example with similar elision of the comma between the first argument and the variadic arguments.)
The compiler prefers the other overload when you pass two arguments because, during overload resolution, an ellipsis conversion sequence is always ranked dead last when ranking viable overloads. ([over.ics.rank])
The compiler prefers this first overload when a single argument is passed because simply, the ellipsis is not matched (because there is nothing to match). This prevents the function from being considered as an ellipsis conversion sequence. Normal function template ranking then happens and it is determined that this function is more specialized than the variadic one ([temp.deduct.partial])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With