Reputation: 337
The following snippet is from the book C++ templates 2nd edition.
template<typename T1, typename T2>
auto max (T1 a, T2 b)
{
return b < a ? a : b;
}
template<typename RT, typename T1, typename T2>
RT max (T1 a, T2 b)
{
return b < a ? a : b;
}
auto b = ::max<long double>(7.2, 4); // uses second template
My question is why ::max(7.2, 4) used the second template? Shouldn't both function templates match since long double can be the type of T1 or RT? Any hints? Thanks!
Upvotes: 1
Views: 163
Reputation: 69
I think it's because T1
and T2
can be made auto by the compiler as the argument you passed on (7.2,4)
(T1
now will be double
and T2
now will be int
or long
) but you also include another typename (and you don't have any other overload which accepts one typename) so the compiler thinks long double
is the first argument of the second overload and auto the other twos.
Upvotes: 0
Reputation: 172864
For the 1st overload, if T1
is specified as long double
, and pass 7.2
which is a double
, the implicit conversion from double
to long double
is required. For the 2nd overload, RT
is specified as long double
, and T1
will be deduced as double
, so it's an exact match and wins in overload resolution.
If you specify template argument as double
as ::max<double>(7.2, 4);
, both of them are exact match and the call will be ambiguous.
Upvotes: 2