2013-02-27 11 views
10

私はC++ 11標準(よく、n3242ドラフト)とインターネットを精査しましたが、正確な答えは見つかりませんでした。以下のコードは、clang 3.2およびg ++ 4.7.2とVisual Studio 2010で正常にコンパイルされますが、代わりにエラーが発生することが予想されます。 typedefと同じスコープで同じ名前の宣言を使用

#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 

打ち鳴らすとg ++ はint型であることを示していると思われる実行ファイルの印刷の "i" を、生成され、typedefが勝ちました。 clは、 "class a_ns :: a_t"という実行可能ファイルを生成しました。これは、Visual Studioが宣言を使用した方が好きだったようです。

次の標準的な抜粋に従ってコードをコンパイルしないと思います。私は、すでに「範囲内の宣言と宣言の競合を使用する」というようなエラーが予想されます。

7.1.3.6 Similarly, in a given scope, a class or enumeration shall not be declared with the same name as a typedef-name that is declared in that scope and refers to a type other than the class or enumeration itself.

7.3.3.1 A using-declaration introduces a name into the declarative region in which the using-declaration appears.

7.3.3.2 Every using-declaration is a declaration [...]

あり、おそらく何か私は、この動作を説明し、標準で行方不明です(または私は明白なことを見てあまりにも疲れている)のですが、私はそれを見つけるように見えることはできません。

ありがとうございます。

答えて

4

これは正しいことです。あなたが示したことは、コードを無効にします。それも無効にする3.3.1p4もあります(7.3.3p13参照)。

現実のテストでは、ICCでテストしたところ、期待どおりに拒否しました。

+0

'main()'の本体が空であれば、そのプログラムも無効でしょうか? 7.1.3/6節では、 "*与えられたスコープでは、typedef指定子は、そのスコープで宣言された型の名前を別の型を参照するために**再定義するために使用してはならない* [例:' class complex {/ ... /}; typedef int complex; //エラー:再定義 '-end example *] "*。この問題では、 'typedef'は名前を「再定義」しません。 'using'宣言の後に移動すると、すべてのコンパイラがエラーを出します。 –

+0

@andy mainが空であれば、私たちが見つけた引用によれば、それも無効になるでしょう。他の引用符も適用されるかどうかは関係ありません。通常、クラスA {}に対して名前の再定義が行われます。 typedef AA; '(最初はクラス名だけですが、typedef-nameでもあります)名前は再定義されます。なぜなら、後で名前は1つだけですが、両方の構文属性を持つからです。 Cモデル)。 –

+0

よろしくお願いいたします。 +1 –

関連する問題