Willi
Willi

Reputation: 337

Overloading Function templates Rules

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

Answers (2)

KhiemGOM
KhiemGOM

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

songyuanyao
songyuanyao

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

Related Questions