模板func和非模板func调用顺序
Template func and non template func call order
在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
是可见的)并且当模板被实例化时,但在实例化时,仅适用于从属名称,并且仅使用ADL。在代码中,max
是一个从属名称,但符号触发ADL的是std::vector
(引入std
)和int
不添加任何内容,甚至不添加全局命名空间。所以未找到非模板CCD_ 8。
这些规则是C++委员会最后正式制定的规则之一编译器不可能在一夜之间改变,所以实际上,如果编译器的日期在1995年之前的任何时候,您可能会期望标准前行为。对于以后的任何事情,我倾向于认为它是编译器错误,但是。。。编译器必须支持现有代码,并且理想情况下,以后的编译器可以选择使用以前的名称查找规则。(我说理想情况下,因为有两组不兼容的名称查找规则显然是不平凡的。只得到一套正确对于大多数编译器实现者来说已经足够困难了。)
众所周知,微软的模板实现即使在今天也不符合标准。
Imax
中max
的调用取决于T,因此应在模板定义上下文中搜索max(模板max所在),并与实例化上下文中的参数相关查找相结合。ADL不应该找到独立的最大值,因为int
没有关联的命名空间。所以我认为gcc是正确的。
注意,如果你有轻微的变化:
#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查找找到非模板最大值。
- 什么时候调用组成单元对象的析构函数
- 对RValue对象调用的LValue ref限定成员函数
- 为什么使用 "this" 指针调用派生成员函数?
- 函数调用中参数的顺序重要吗
- OpenGL - 在抛出"__gnu_cxx::recursive_init_error"实例后终止调用?
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 为什么我的C#代码在调用回C++COM直到Task时会暂停.等待/线程.加入
- 在c++类上调用void函数
- 为什么 std::unique 不调用 std::sort?
- 表观调用前面的表达式必须具有指向 func 类型的指针
- 如何在派生类中不显式调用base::func()的情况下从基类执行虚拟函数
- 为什么无法在 Cocoa 应用程序调用的 C++ func 中嵌入自定义 Python 模块
- 有没有办法查看此语句"Student s3=func(s1, s4)"将调用哪个构造函数?
- 重载的 'func(char*&)' 的调用是不明确的
- 模板func和非模板func调用顺序
- set_new_handler (std::new_handler func) 失败后的构造函数调用,用于内存分配失败
- 属性错误:"模块"对象没有属性"func",仅通过C++调用
- 从外部使用"class::func()"调用非静态函数或构造函数
- 如何使用派生类实例调用基类重载的func,
- 使用 EXC_BAD_ACCESS(..) 从 C++ 调用 Swift func