web-dev-qa-db-ja.com

私の列挙型はクラスまたは名前空間ではありません

こんにちは、MyCode.hおよびMyCode.cppというファイルがあります

MyCode.hで宣言しました

enum MyEnum {Something = 0, SomethingElse = 1};

class MyClass {

MyEnum enumInstance;
void Foo();

}; 

次に、MyCode.cppで:

#include "MyCode.h"

void MyClass::Foo() {
    enumInstance = MyEnum::SomethingElse;
}

しかし、g ++でコンパイルすると、「MyEnum」はクラスまたは名前空間ではありませんというエラーが表示されます...

(MS VS2010では正常に動作しますが、Linux g ++では動作しません)

何か案は?ありがとうトーマス

59
Prof

構文MyEnum::SomethingElseはMicrosoft拡張機能です。たまたま私が好きなものですが、標準C++ではありません。 enum値が周囲のネームスペースに追加されます。

 // header
 enum MyEnum {Something = 0, SomethingElse = 1};

 class MyClass {

 MyEnum enumInstance;
 void Foo();

 }

 // implementation
 #include "MyClass.h"

 void Foo() {
     enumInstance = SomethingElse;
 }
63
Max Lybbert

スコープ付き列挙型は、C++ 0xまで存在しません。当分の間、あなたのコードは

enumInstance = SomethingElse;

列挙の定義を独自の名前空間または構造体内に置くことにより、人工的なスコープ付き列挙を作成できます。

51
ildjarn

実際、C++ 0xはその機能を許可しています。次のコマンドラインフラグを使用して、gccで正常に有効にできます。-std = c ++ 0x

これはgccバージョン4.4.5でした

31
gregn3

他の回答で説明しているように:構文MyEnum::SomethingElseは、コンパイラが非標準の拡張機能でサポートしていない限り、通常のC++ 98列挙型では無効です。

私は個人的に宣言が好きではないenum MyEnum {A, B};列挙値の使用中にタイプ名が存在しないため。これにより、現在の名前空間で名前の競合が発生する可能性があります。

そのため、ユーザーは各列挙値で型名を参照する必要があります。 Aを2回宣言しないようにする例:

enum MyEnum {MyEnum_A, MyEnum_B};
void A(void) {
    MyEnum enumInstance = MyEnum_A;
}

特定の名前空間または構造を使用することを好みます。これにより、最新のC++スタイルで列挙値を参照できます。

namespace MyEnum {
    enum Value {A,B};
}
void A(void) {
    MyEnum::Value enumInstance = MyEnum::A
}
2
Jonathan