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

Ale*_*der 6 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';   
}
Run Code Online (Sandbox Code Playgroud)

代码打印

template
template
7
Run Code Online (Sandbox Code Playgroud)

Pra*_*ian 8

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

int const& max (int const& a, int const& b);
Run Code Online (Sandbox Code Playgroud)

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

实例


至于为什么会这样,我相信§3.4.1/ 1 [basic.lookup.unqual]就是答案.

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

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

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