Template overload resolution with multiple viable types
This is because the first max
is more specialized as the second max
.
What happens during template overload resolution is that the compiler instantiates both templates and then asks "Which one is more specialized?"
In a nutshell it asks, given overload A and overload B, "Can I instantiate B with the deduced type(s) from A, but not vice versa?" If so, then A is more specialized than B (we can go from A to B, but not back). It does the same thing the other way. If both can be instantiated from each other, it is ambiguous and a compiler error.
In reality, we don't use the actual type for T
(int
in this case), but some made-up type ("synthesized type").
In your case, the first template requires both types to be the same:
template<typename T>
auto max(T a, T b)
So we have max<int>
(or max<synthesized1>
)
Can we instantiate the second one given synthesized1
for T
? Sure thing, T1 = synthesized1
and T2 = synthesized1
.
Can we go the other way though?
The second template has two parameters, so it allows that a
and b
are different types, so it is more general. It gets instantiated with two synthesized types:
template<typename T1, typename T2>
auto max (T1 a, T2 b)
so, max<synthesized2, synthesized3>
.
Can we instantiate the first max<T>
with types synthesized2
and synthesized3
? Nope, it requires that a
and b
have the same type. Therefore the first template is more specialized, and the compiler chooses it.
Refer to [temp.deduct.partial] for standardese