问题描述
在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 ofthe pre-standard compilers I know would defer name-lookup toinstantiation.) Since C++89, you should get templatemax
; name lookupoccurs in two phases: when the template is defined (at which point, onlythe templatemax
is visible), and when the template is instantiated,but at the instantiation point, only for dependent names, and only usingADL. In your code,max
is a dependent name, but the symbolstriggering ADL arestd::vector
(which draws instd
) andint
, whichdoesn't add anything, not even the global namespace. So thenon-templatemax
is not found.These rules were among the last formalized by the C++ committee, andcompilers can't change overnight, so practically speaking, if thecompiler dates from anytime before 1995, you can probably expect thepre-standard behavior. For anything later, I'd tend to consider it acompiler error, but... compilers have to support existing code, andideally, later compilers will have an option to use the previous namelookup rules. (I say ideally, because having two incompatible sets ofname lookup rules is decidedly non-trivial. Just getting one setcorrect is difficult enough for most compiler implementors.)
And it's fairly well known that Microsoft's implementation of templatesis not standard conformant, even today.
这篇关于模板func和非模板func调用顺序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!