Both overloads are viable, but the former is more specialized than the latter, and therefore it gets picked by overload resolution.
Per paragraph 13.3.3/1 of the C++11 Standard on overload resolution:
[...] a viable function F1
is defined to be a better function than another viable function
F2
if for all arguments i
, ICSi(F1)
is not a worse conversion sequence than ICSi(F2)
, and then
— for some argument j, ICSj(F1)
is a better conversion sequence than ICSj(F2)
, or, if not that,
— the context is an initialization by user-defined conversion (see 8.5, 13.3.1.5, and 13.3.1.6) and the
standard conversion sequence from the return type of F1 to the destination type (i.e., the type of the
entity being initialized) is a better conversion sequence than the standard conversion sequence from
the return type of F2
to the destination type. [ ... ] or, if not that,
— F1
is a non-template function and F2
is a function template specialization, or, if not that,
— F1
and F2
are function template specializations, and the function template for F1
is more specialized
than the template for F2
according to the partial ordering rules described in 14.5.6.2.
The process of determining which of two function templates is more specialized than the other is outlined in paragraph 14.5.6.2/2:
Partial ordering selects which of two function templates is more specialized than the other by transforming
each template in turn (see next paragraph) and performing template argument deduction using the function
type. The deduction process determines whether one of the templates is more specialized than the other. If
so, the more specialized template is the one chosen by the partial ordering process.
foo<int>(0)
butfoo(0)
instead (No type deduction for the identity meta function). @Andy Prowl: I dont want to question your answer put point out that your reasoning is not as obvious as it may appear. Give the foo parameter a default value and callfoo<int>()
without parameter. Your argumentation should still apply but now the overloads are indeed ambiguous as HighCommander4 expected. Explicit template instantiation of function templates is complicated. – Gandy