私は最近これに遭遇しました:
static enum Response{
NO_ERROR=0,
MISSING_DESCRIPTOR,
...
};
コンパイルし、Microsoft VS2005で動作します。ただし、 'static'修飾子が何をするのかわからない。次と違うものはありますか?
enum Response {
NO_ERROR=0,
MISSING_DESCRIPTOR,
...
};
省略記号を削除しただけの正確なコードは、有効なC++ではありません。 static
宣言でenum
ストレージクラス指定子を使用することはできません。そこでは意味がありません(static
として宣言できるのは、オブジェクト、関数、および匿名ユニオンのみです)。
ただし、enum
と変数をすべて1つの宣言で宣言できます。
static enum Response {
NO_ERROR = 0,
MISSING_DESCRIPTOR
} x;
ここのstatic
はx
に適用され、あなたが言った場合と事実上同じです:
enum Response {
NO_ERROR = 0,
MISSING_DESCRIPTOR
};
static Response x;
驚くべきことに、他のdecl-specifiersもそこに入れることができます。
VS2008で正常にコンパイルされます。
auto const enum TestEnum {
Why,
Does
};
register volatile enum TestEnum2 {
This,
Work
};
しかし、それはまったく意味がありません:)
私はここの問題は構文解析にあると思われます、なぜならこのようなコード:
enum TestEnum3 { Hello, World }; // Define enum
enum TestEnum3 x = World; // Use enum
次のように書くこともできます。
enum TestEnum3 { Hello, World } x = World; // Define and use enum.
興味深いことに、VS2008でこれを行うと気づきます。
enum TestEnum3 { Hello, World };
const enum TestEnum3 e3 = World;
const enum TestEnum4 { F, M, L } e4 = F;
e3 = Hello; // error C2166: l-value specifies const object (Good!)
e4 = M; // NO ERROR here though - why?
したがって、それらはTestEnum4
場合は、const
decl-specifierを捨てているようです。すべて非常に奇妙です。
static enum Response { /*... */ };
C++ではstatic
enumを定義できません。 static
は、enumのvariableのみであり、type自体ではありません!
GCC
version 4.3.4
を使用してコードをコンパイルすると、次のエラーが発生します。
prog.cpp:7:エラー:ストレージクラスはオブジェクトと関数にのみ指定できます
Ideoneでオンラインで自分自身を参照してください: http://www.ideone.com/cI1bt
それがすべてだと思います。
-
ただし、typeenum Response
を独自の翻訳単位に制限する場合は、名前のない名前空間を使用できます。このトピックをご覧ください:
標準
C++ 11 N3337標準ドラフト Annex C 7.1.1は、Cでは許可されたが、効果はなく、C++では違法になったと述べています。
変更:C++では、静的または外部指定子はオブジェクトまたは関数の名前にのみ適用できます。これらの指定子を型宣言で使用することは、C++では無効です。 Cでは、これらの指定子は型宣言で使用されると無視されます。例:
static struct S { // valid C, invalid in C++
int i;
};
根拠:ストレージクラス指定子は、型に関連付けられている場合、意味を持ちません。 C++では、静的ストレージクラス指定子を使用してクラスメンバーを宣言できます。型宣言でストレージクラス指定子を許可すると、コードがユーザーを混乱させる可能性があります。
struct
と同様に、enum
も型宣言です。
実装根拠
Enum定義にはストレージがなく、変数や関数などのオブジェクトファイルにシンボルを生成しません。コンパイルと逆コンパイルを試してください:
struct S { int i; int j; };
int i;
で:
g++ -c main.c
nm main.o
S
シンボルはありませんが、i
シンボルはあります。
コンパイラーが列挙値を認識すると、コンパイルされたコードにそのまま挿入されます。コンパイル時の定数であるため、これはもちろん機能します。
したがって、ヘッダーファイルに含める必要があります。
こちらもご覧ください:
static struct
に関する関連質問: Cプログラミングで静的構造体を使用する理由と理由「;」 enumブロックの後の下位互換性のためにオプションです。 notは、名前付き型のその言語でそのようなセマンティクスを許可します。 static、publicなどには特別な考慮事項があります。名前空間にフィールドやメソッドなどのメンバーを含めることはできません。
タグが必要:
ArgTypes var = ArgTypes.CUT;
「;」が必要列挙ブロックの最後。グローバル名前空間変数、列挙などの場合、デフォルトではstaticです。
int type;
typedef enum {
TOKENIZE,
CUT
} ArgTypes;
type = TOKENIZE; /* <ArgTypes>::TOKENIZE */
type = ArgTypes::CUT;
// Recommended Use
enum ArgTypes {
TOKENIZE,
CUT
}; /* Same as above */
enum Test {
TOKENIZE,
CUT
} ArgTypes;
type = ArgTypes::TOKENIZE;
type = CUT; /* Assign type => <Test>.CUT */
type = Test::CUT;
enum {
TOKENIZE,
CUT
} ArgTypes; /* Unamed.. requires tag */
type = TOKENIZE; /* <unamed>.TOKENIZE=0 => #define TOKENIZE 0*/
type = ArgTypes::TOKENIZE; /* ** ERROR ** */
なぜstaticが使用されたのか、なぜコンパイルされるのかわからない。単なる列挙型応答である必要があります。列挙子は静的データではありません。