首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >模板函数和非模板函数调用顺序

模板函数和非模板函数调用顺序
EN

Stack Overflow用户
提问于 2012-08-29 17:13:04
回答 2查看 134关注 0票数 2

在Linux中,我得到了

代码语言:javascript
复制
template max() is called

但在Windows下,我得到了

代码语言:javascript
复制
non-template max() is called

为什么?在Linux上,我用的是gcc 4.5,在Windows上,我用的是VS2008。

代码语言:javascript
复制
#include <iostream>
#include <vector>

template < typename T > 
inline void max( const int& a, const T& b ) 
{
    std::cout << "template max() is called" << std::endl;
}

template < typename T > 
inline void Imax( const int& a, const std::vector<T>& b)
{
    max(a, b[0]);
}

inline void max( const int& a, const int& b ) 
{
    std::cout << "non-template max() is called" << std::endl;
}

int main()
{
    std::vector<int> v;
    v.push_back(1);
    Imax(1, v);       
    return 0;
}
EN

回答 2

Stack Overflow用户

发布于 2012-08-29 17:27:28

在标准之前的C++中,您可能会得到非模板max。(没有标准,很难说应该得到什么,但我所知道的所有准标准编译器都会将名称查找推迟到实例化。)从C++89开始,您应该获得模板max;名称查找分两个阶段进行:定义模板时(此时,只有模板max可见)和实例化模板时,但在实例化时,仅用于依赖名称,并且仅使用ADL。在您的代码中,max是一个依赖名称,但是触发ADL的符号是std::vector (它在std中绘制)和int,它不会添加任何东西,甚至不会添加全局名称空间。因此找不到非模板max

这些规则是C++委员会最后正式制定的规则之一,编译器不可能在一夜之间改变,所以实际上,如果编译器的日期是1995年之前的任何时候,您可能会看到准标准行为。对于以后的任何事情,我倾向于认为这是一个编译器错误,但是...编译器必须支持现有代码,理想情况下,以后的编译器可以选择使用以前的名称查找规则。(我说的是理想情况,因为拥有两组不兼容的名称查找规则肯定不是无关紧要的。对于大多数编译器实现者来说,仅仅纠正一组代码就已经够难的了。)

众所周知,即使在今天,微软的模板实现也不符合标准。

票数 4
EN

Stack Overflow用户

发布于 2012-08-29 17:26:53

Imaxmax的调用依赖于T,因此max应该在模板定义上下文(模板max所在的位置)中进行搜索,并与实例化上下文中的参数相关查找相结合。由于int没有关联的命名空间,因此ADL不应该找到最大自由站立空间。所以我的观点是,gcc是正确的。

请注意,如果您有细微的变化:

代码语言:javascript
复制
#include <iostream>
#include <vector>

struct S {};

template < typename T > 
inline void max( const S& a, const T& b ) 
{
    std::cout << "template max() is called" << std::endl;
}

template < typename T > 
inline void Imax( const S& a, const std::vector<T>& b)
{
    max(a, b[0]);
}

inline void max( const S& a, const S& b ) 
{
    std::cout << "non-template max() is called" << std::endl;
}

int main()
{
    std::vector<S> v;
    v.push_back(S());
    Imax(S(), v);       
    return 0;
}

这里,全局名称空间与S相关联,因此在实例化时通过ADL查找找到非模板max。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12174493

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档