为什么编译器会在下面选择模板版本?

时间:2014-04-11 00:54:19

标签: c++ templates c++11

编译器使用模板版本来计算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';   
}

The code prints

template
template
7

1 个答案:

答案 0 :(得分:8)

您的非模板版max()的定义在呼叫网站上不可见,之后会定义。将该函数移到3参数max()之上或在调用站点上方添加原型。

int const& max (int const& a, int const& b);

现在在两种情况下都选择了非模板版本。

Live example


至于为什么会出现这种情况,我相信§3.4.1/ 1 [basic.lookup.unqual] 会有答案。

  

在3.4.1中列出的所有情况下,在每个相应类别中列出的顺序中搜索范围;一旦找到名称的声明,名称查找就会结束。如果没有找到声明,该程序就会形成错误。

请注意,参数依赖的名称查找不适用于您的情况,因为max的参数是int,而不是用户定义的类型。只应用非限定名称查找,因此,如上所述,查找在第一次匹配(max()的函数模板版本)找到时停止。

引用部分的最后一句也解释了为什么如果你注释掉max()的函数模板版本,你的代码将无法编译。