重载函数模板规则

Overloading Function templates Rules

以下片段摘自《C++ 模板》第 2 版。

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

我的问题是为什么::max(7.2, 4) 使用了第二个模板?既然 long double 可以是 T1 或 RT 的类型,两个函数模板不应该匹配吗?有什么提示吗?谢谢!

对于第一个重载,如果 T1 被指定为 long double,并传递 7.2 这是一个 doubledouble 的隐式转换到 long double 是必需的。对于第二次重载,RT 被指定为 long doubleT1 将推导为 double,因此它是一个精确匹配并在重载决策中获胜。

如果将模板参数指定为 double::max<double>(7.2, 4);,两者都是完全匹配,调用将产生歧义。

我认为这是因为 T1T2 可以由编译器自动作为您传递给 (7.2,4) 的参数(T1 现在将是 doubleT2 现在将是 intlong) 但你还包括另一个类型名(并且你没有任何其他接受一个类型名的重载)所以编译器认为 long double 是第二个重载的第一个参数,其他两个都是 auto。