c++ - 模板函数和非模板函数的调用顺序

标签 c++ linux templates

在 Linux 中我得到

template max() is called

但是在 Windows 下我得到了

non-template max() is called

为什么?在 Linux 中,我使用 gcc 4.5,在 Windows 中,我使用 VS2008。

#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;
}

最佳答案

在准标准 C++ 中,您可能会得到非模板 max。 (没有标准,很难说您应该得到什么,但是所有 我知道的准标准编译器会将名称查找推迟到 实例化。)从 C++89 开始,你应该得到模板 max;名称查询 发生在两个阶段:定义模板时(此时,仅 模板 max 是可见的),当模板被实例化时, 但在实例化点,仅用于相关名称,并且仅使用 日常事件。在您的代码中,max 是从属名称,但符号 触发 ADL 的是 std::vector(在 std 中绘制)和 int,它 不添加任何东西,甚至不添加全局命名空间。所以 未找到非模板 max

这些规则是 C++ 委员会最后正式制定的规则之一,并且 编译器不可能一夜之间改变,所以实际上,如果 编译器可以追溯到 1995 年之前的任何时候,您可能会期望 前标准行为。对于以后的任何事情,我倾向于将其视为 编译器错误,但是......编译器必须支持现有代码,并且 理想情况下,以后的编译器将可以选择使用以前的名称 查找规则。 (我说理想情况下,因为有两套不兼容的 名称查找规则绝对不重要。刚入手一套 对于大多数编译器实现者来说,正确已经足够困难了。)

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

关于c++ - 模板函数和非模板函数的调用顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12174493/

相关文章:

c++ - 在映射键的 vector 中查找多个字符串

linux - ImageMagick:如何在调整大量图像文件大小时实现低内存使用?

c++ - 使用枚举类作为模板参数缩短模板函数调用

c++ - C 与 C++ 中的枚举存储差异

c++ - 如何找出试图加载 libmysqlclient_r.so 库的内容

linux - 删除空字符(Shell 脚本)

c++ - 传递对 Variadic 模板的引用

symfony - FOSUserBundle 理解 twig 模板变量

c++ - 将共享内存地址值打印到命令行

php - 在 CLI 和 Web 上调用时,如何让 PHP 使用相同的 APC 缓存?