编译器使用模板版本来计算t = max(a, b)
和max(t, c)
。支持此标准的任何引用都是受欢迎的。
#include <iostream>
template <typename T>
inline T const& max (T const& a, T const& b)
{
std::cout << "template" << '\n';
return a < b ? b : a;
}
template <typename T>
inline T const& max (T const& a, T const& b, T const& c)
{
return max (max(a,b), c);
}
inline int const& max (int const& a, int const& b)
{
std::cout << "non-template" << '\n';
return a <b ? b : a;
}
int main()
{
std::cout << max(3, 5, 7) << '\n';
}
template
template
7
答案 0 :(得分:8)
您的非模板版max()
的定义在呼叫网站上不可见,之后会定义。将该函数移到3参数max()
之上或在调用站点上方添加原型。
int const& max (int const& a, int const& b);
现在在两种情况下都选择了非模板版本。
至于为什么会出现这种情况,我相信§3.4.1/ 1 [basic.lookup.unqual] 会有答案。
在3.4.1中列出的所有情况下,在每个相应类别中列出的顺序中搜索范围;一旦找到名称的声明,名称查找就会结束。如果没有找到声明,该程序就会形成错误。
请注意,参数依赖的名称查找不适用于您的情况,因为max
的参数是int
,而不是用户定义的类型。只应用非限定名称查找,因此,如上所述,查找在第一次匹配(max()
的函数模板版本)找到时停止。
引用部分的最后一句也解释了为什么如果你注释掉max()
的函数模板版本,你的代码将无法编译。