模板func和非模板func调用顺序 [英] Template func and non template func call order

查看:80
本文介绍了模板func和非模板func调用顺序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Linux中,我得到

 模板max()被调用
pre>

但在Windows下我得到

  )被称为

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

  #include< iostream> 
#include< vector>

template<类型名T>
inline void max(const int& a,const T& b)
{
std :: cout< template max()被称为<< std :: endl;
}

template<类型名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< 非模板max()被称为< std :: endl;
}

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


解决方案

你可能会得到非模板 max
(没有标准,很难说你应该得到什么,但是所有的
我预知的标准编译器将名称查找推迟到
实例化。)由于C ++ 89,你应该得到模板 max ;名称查找
发生在两个阶段:当定义模板时(此时只有
模板 max 可见)被实例化,
但是在实例化点,仅用于依赖名称,并且仅使用
ADL。在你的代码中, max 是一个依赖名称,但触发ADL的符号
std :: vector (它引入 std )和 int ,其中
不添加任何东西,命名空间。因此,找不到
非模板 max



这些规则是最后一个C ++委员会和
编译器不能在一夜之间改变,所以实际上,如果
编译器从1995年之前的任何时候开始,你可能期望
预标准行为。对于任何事情,我倾向于认为它是一个
编译器错误,但是编译器必须支持现有的代码,理想情况下,
,后来的编译器将有一个选项使用以前的名称
查找规则。 (我说的理想情况下,因为有两个不兼容的
名称查找规则的集合是决定性的不重要的,只是得到一个集合
正确对于大多数编译器实现者来说是困难的。)



相当熟悉的是,Microsoft的模板实现
是不符合标准的,甚至今天。


In Linux I get

template max() is called

But under Windows I get

non-template max() is called

Why? In Linux, I use gcc 4.5 and in Windows I use 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;
}

解决方案

In pre-standard C++, you would likely get the non-template max. (Without a standard, it's hard to say what you should get, but all of the pre-standard compilers I know would defer name-lookup to instantiation.) Since C++89, you should get template max; name lookup occurs in two phases: when the template is defined (at which point, only the template max is visible), and when the template is instantiated, but at the instantiation point, only for dependent names, and only using ADL. In your code, max is a dependent name, but the symbols triggering ADL are std::vector (which draws in std) and int, which doesn't add anything, not even the global namespace. So the non-template max is not found.

These rules were among the last formalized by the C++ committee, and compilers can't change overnight, so practically speaking, if the compiler dates from anytime before 1995, you can probably expect the pre-standard behavior. For anything later, I'd tend to consider it a compiler error, but... compilers have to support existing code, and ideally, later compilers will have an option to use the previous name lookup rules. (I say ideally, because having two incompatible sets of name lookup rules is decidedly non-trivial. Just getting one set correct is difficult enough for most compiler implementors.)

And it's fairly well known that Microsoft's implementation of templates is not standard conformant, even today.

这篇关于模板func和非模板func调用顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆