私はC++11標準(まあ、n3242ドラフト)とインターネットを調べましたが、正確な答えを見つけることができませんでした。以下のコードは、clang3.2とg++ 4.7.2、およびVisual Studio 2010で正常にコンパイルされますが、代わりにエラーが発生することが予想されます。
#include <iostream>
#include <typeinfo>
typedef int a_t;
namespace a_ns
{
class a_t {};
}
using a_ns::a_t;
int main()
{
a_t a;
std::cout << typeid(a).name() << std::endl;
return 0;
}
で構築:
clang -std=c++11 -pedantic -Wall -o a a.cpp -lstdc++
g++ -std=c++11 -pedantic -Wall -o a a.cpp -lstdc++
cl -EHsc -GR a.cpp
clangおよびg++で生成された実行可能ファイルは「i」を出力します。これは、aがint型であり、typedefが優先されていることを示しているようです。clで生成された実行可能ファイルは、「class a_ns :: a_t」を出力します。これは、VisualStudioがusing宣言をより気に入っていることを示しているようです。
次の標準的な抜粋に従ってコードがコンパイルされないことを期待します。「宣言を使用するターゲットがすでにスコープ内にある宣言と競合する」と同様のエラーが発生することが予想されます。
7.1.3.6同様に、特定のスコープでは、クラスまたは列挙は、そのスコープで宣言され、クラスまたは列挙自体以外の型を参照するtypedef-nameと同じ名前で宣言されてはなりません。
7.3.3.1 using-declarationは、using-declarationが表示される宣言型領域に名前を導入します。
7.3.3.2すべてのusing-declarationは宣言です[...]
おそらく、この動作を説明する標準に欠けているものがあります(または、疲れすぎて明白なものを見ることができません)が、それを見つけることができないようです。
ありがとうございました。