我測試了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有相同的問題。 –