2017-11-19 7 views
14

C++ 14(正確には、N4296)が7.2で、列挙に関して言うC++ 14では、スコープがスコープが変更されている場合、再宣言された列挙体の列挙子が宣言されていますか? 11:

各列挙名と各スコープ外の列挙子を直ちに列挙指定子を含ん範囲 で宣言され。

ここで、名前空間Nには、列挙型Eの不透明列挙宣言が含まれており、後でその列挙がグローバル名前空間から完全に宣言されるとどうなりますか?列挙子がグローバル名前空間か名前空間Nで見つかるか?

もちろん、スコープのない列挙を不透明に宣言するためには、それは固定された基底型を持ちます。次のコードを考えてみましょう。

namespace N { enum E : int; } 
enum N::E : int {A,B}; 

namespace N { 
    int foo() { 
     return int(::N::B); 
    } 
} 

int bar() { 
    //return int(::A); 
    return int(A); 
} 

clang++ -std=c++14は言わないのでbarの最初の行は、コメントアウトされています

グローバル名前空間に「A」という名前のメンバー。あなたは単に「A」を意味しましたか?

GCCはbar()の両方の行をコンパイルできません。だから、gccとclangの両方が名前空間Nの列挙を宣言します。

だから私の質問は以下のとおりです。

  1. immediatelly列挙型指定子が含まれているスコープとは何ですか? (私はそれがグローバルな名前空間の範囲です)。
  2. グローバル名空間で列挙子ABを定義する必要がありますか?
  3. bar関数では、::Aは列挙子を参照していませんが、単純なAはどうしてですか?
  4. N::fooの式::N::Bが列挙子を示しているのはなぜですか?

EDIT 1:元の宣言はenum ::N::E : int {A,B};であったが、GCCは、それを解析することができなかった(bug report)ので、私はenum N::E : int {A,B};

EDIT 2使用につながるコロンを除去:打ち鳴らすの挙動がbug

です
+4

'戻りINT(A)の成功コンパイル:このように、それだけで、その後のように定義されるべきであるN.

バー機能の範囲にアクセスすることができます* clang *のバグ](https://godbolt.org/g/6rjfZd)。 – Constructor

+0

GCCは[宣言](https://godbolt.org/g/VG1vBJ) –

+0

をコンパイルしていません。私が見るように、* gcc *のバグです。 – Constructor

答えて

0

エニュメレーションEは、グローバル名前空間内でその定義が設定されていても、名前空間N内で宣言されます。 `[自明のように見える。

int bar() { 
    return int(N::A); 
    //SAME AS --> return int(::N::A); 
} 
関連する問題