If we have a template function which takes a non-type parameter of type int
or short
the compiler complains about the ambiguity of the following ca
Here's what happens when you write f<0>()
.
The compiler looks up f
, and finds two function template declarations:
template void foo();
template void foo();
The compiler sees the explicit template argument list and attempts to substitute it into each function template declaration:
template void foo(); // with I = 0
template void foo(); // with S = 0
Substitution succeeds in both cases because 0
is an int
, and can be converted to short
, and the conversion is an allowed conversion in this context.
After substitution, two candidate function specializations are produced. Both are viable. Overload resolution is then performed - and since the signature is identical and no tiebreaker applies, overload resolution fails and the call is ambiguous.
The point here is that the normal overload resolution rules do not apply to template arguments. The conversions for template arguments are applied in an earlier stage, before the regular overload resolution takes place.