What is the difference between variadic template and ellipsis?

What even is the first overload?

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.)

Why do we see that specific output?

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])


Following overload_resolution#Best_viable_function

  • For f(1),

    We go though 5)

    or, if not that, F1 and F2 are both template specializations and F1 is more specialized according to the partial ordering rules for template specializations

    And from Function_template_overloading

    After considering every P and A in both directions, if, for each type that was considered, [..]

    In case of a tie, if one function template has a trailing parameter pack and the other does not, the one with the omitted parameter is considered to be more specialized than the one with the empty parameter pack.

    So ellipsis function template<typename T> void foo(T,...) is considered more specialized than variadic template<typename ...Ts> void foo(Ts...).

  • for f(1, 2)

    Reading Ranking_of_implicit_conversion_sequences

    In variadic version we have exact match, whereas ellipsis has ellipsis conversion sequence

    So variadic is better match.