我测试了Xcode 4.1和Visual Studio 2008上的C++标准ISO/IEC 14882-03 14.6.1/9中的代码。这两种编译器都与标准的预期结果不同。类模板中名称解析的实际结果与C++ 03标准不同
代码粘贴在下面。
#include <stdio.h>
#include <iostream>
using namespace std;
void f(char);
template <class T > void g(T t)
{
f(1);
f(T(1));
f(t);
}
void f(int);
void h()
{
g(2);
g('a');
}
void f(int)
{
cout << "f int" << endl;
}
void f(char)
{
cout << "f char" << endl;
}
int main() {
h();
return 0;
}
作为标准的描述。预期的输出应该是
f char
f int
f int
f char
f char
f char
构建并运行Xcode 4.1上的代码。输出如下。在构建设置中,我尝试将“C/C++/Object-C编译器”更改为Apple LLVM Compiler 2.1,Gcc 4.2和LLVM GCC 4.2。输出是相同的。
f char
f char
f char
f char
f char
f char
构建并运行Microsoft Visual Studio 2008上的代码。输出如下。
f int
f int
f int
f int
f char
f char
该标准的描述(14.6.1/9)被粘贴在下面。
如果名称不依赖于模板参数(如14.6.2中定义),则该名称的声明(或一组声明)应在名称出现在模板定义;该名称被绑定到在该点发现的声明(或声明),并且该绑定不受在实例化处可见的声明的影响。 [实施例:
void f(char);
template<class T> void g(T t)
{
f(1); // f(char)
f(T(1)); // dependent
f(t); // dependent
dd++; // not dependent
}
void f(int);
double dd;
void h()
{
// error: declaration for dd not found
g(2); // will cause one call of f(char) followed // by two calls of f(int)
g(’a’); // will cause three calls of f(char)
末端示例]
的代码是公形成到编译器,但输出是不同的。将此代码移植到不同的平台上将是非常危险的。
有人有背景为什么这些编译器不遵循标准?
编辑于2011-11-10
每http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#197,在标准的例子是错误的。我在Clang和Gcc上测试下面的代码。
#include <stdio.h>
#include <iostream>
using namespace std;
void f(char);
template <class T > void g(T t)
{
f(1);
f(T(1));
f(t);
}
enum E{ e };
void f(E);
void h()
{
g(e);
g('a');
}
void f(E)
{
cout << "f E" << endl;
}
void f(char)
{
cout << "f char" << endl;
}
int main() {
h();
return 0;
}
预期的输出。
f char
f E
f E
f char
f char
f char
感谢,
杰弗里
+1对于第一个问题 –
有趣的是,Clang 2.9与gcc有相同的问题。 –