2016-02-29 7 views
18

列挙型の宣言のポイントは何ですか?それは列挙型の名前の直後ですか?いずれかのその列挙指定子(7.2)またはその最初に列挙宣言のポイント

列挙の宣言のポイントは 識別子直後である(もしあれば):私は、標準C++ 14(n4296)§3.3.2/ 3を見最初

をいずれか早い方 不透明-列挙型宣言(7.2)、しかし、私はそれを再現しようとします。

template <class T> 
struct CL 
{ 
    using UndType = int; 
}; 

enum class E: CL<E>::UndType; //error: E is undefined 

列挙Eため列挙ベースは、識別子の後に配置され、表示されなければならないが、私は、すべてのコンパイラのエラーを持っています。

+1

私は、* opaque-enum-declaration *の ';'( '// error'の前に)あると思います。 – Jarod42

+1

'CL 'では 'E'は実際にはまだ宣言されていません:( – Jarod42

+1

Jarod42、なぜそれはまだ宣言されていませんか?標準では識別子の直後であると言っていますか?それは – user3514538

答えて

13

enum class E : CL<E>::UndType; 

いくつかの現在の実装(テストされたclang ++、g ++、MSVC)では有効な宣言として受け入れられません。彼らは、まだ完成していないタイプのEを受け入れていません。enum-baseCL<E>::UndTypeです。テストされた実装で与えられたエラーは、Eであり、その時点でであることが宣言されています。彼らはenum-baseの終わりに宣言のポイントを置くようですが、完了したら宣言したものとみなします。

仕様を読むとき。

§14.3.1/ 2テンプレート型引数

[注:テンプレート型引数は、不完全型(3.9)であってもよいです。 - エンドノート]

そして

§7.2/ 6列挙宣言

基底型固定されている宣言のその点から不完全型で列挙(3.3.2) enum-base(存在する場合)の直後まで、完全な型になります。

コンパイル可能ですか? CRTP実装の場合と同様です。

これは(すなわち、enum class E : CL<E>::UndType;をコンパイルできなかった)が意図か、それがユースケースとみなされたかどうかは確かです。この仕様から、不透明なenum宣言にはいくつかの "特別な"扱いが与えられています。その基底型とそれが整数型でなければならないという要件。

おそらくコードCWG#1482の解像度でとコンパイルできるはずです。


現在の回避策は...

これは、

enum class E; // default underlying type is int 

最小限の宣言です。

不透明宣言は、次のいずれかです。

enum class E : int; // int base 

以下は完全な定義(列挙子を含む)です。

enum class E : int {/*...*/}; 

また、クラステンプレートを使用するには、別のタイプ(おそらくvoid)も使用できます。

enum class E : CL<void>::UndType; 
+5

http:// jaから。cppreference.com/w/cpp/language/enum、基になる型は宣言の一部です。 'enum class E'は' enum class E:int'と同じです。 'UndType'を' char'に変更すると、エラー[Demo](http://coliru.stacked-crooked.com/a/1b7463cc118c5fd6)が生成されます。 – Jarod42

+1

今は良いですが、 "enum-base *"についての部分が "まだ完成していません"というのはまだ正しくありません。これは 'int'のエイリアスです。 'CL 'が暗黙的にインスタンス化されているときに 'E'が実際に不完全であるという事実は、この場合は無関係です。 @ bogdan。 – bogdan

+1

正しかった、私はそれが問題の要点だと思うが、実装はそれが完全ではないと思う - 私はその部分をどうにかして言い直す必要があると思う。おそらく "CL :: UndType'のベースに未完成の' E'型を受け入れていません。 – Niall