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

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

解决方法

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

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

Live example

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

In all the cases listed in 3.4.1,the scopes are searched for a declaration in the order listed in each of the respective categories; name lookup ends as soon as a declaration is found for the name. If no declaration is found,the program is ill-formed.

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

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

相关文章

文章浏览阅读315次。之前用C语言编过链表,这几天突然想用C+...
文章浏览阅读219次。碰到问题就要记录下来,防止遗忘吧。文章...
文章浏览阅读1.8k次,点赞11次,收藏37次。因为自己对决策树...
文章浏览阅读492次。C++ 设计模式之策略模式
文章浏览阅读683次。我也算是个C++的小白,对于C++中的谓语我...
文章浏览阅读225次。又看了一遍操作符的东西,感觉之前对操作...