Xcode 4.1およびVisual Studio 2008のC++標準ISO/IEC 14882-03 14.6.1/9のコードをテストします。 2つのコンパイラは両方とも、標準の期待される結果とは異なります。クラステンプレートの名前解決の実際の結果は、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でコードをビルドして実行してください。出力は以下の通りです。ビルドの設定では、「Compiler for 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年10月11日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と同じ問題があるようです。 –