サーチ…


基本列挙宣言

標準列挙では、ユーザーは整数セットの有益な名前を宣言できます。これらの名前は集合的に列挙子と呼ばれます。列挙体とそれに関連する列挙子は、次のように定義されます。

enum myEnum
{
    enumName1,
    enumName2,
};

列挙 、他のすべてのタイプとは異なるものです。この場合、この型の名前はmyEnumです。この型のオブジェクトは、列挙体内の列挙子の値を引き継ぐことが期待されます。

列挙体内で宣言された列挙子は、列挙型の型の定数値です。列挙子は型内で宣言されていますが、名前にアクセスするためにはスコープ演算子::は必要ありません。したがって、最初の列挙子の名前はenumName1です。

C ++ 11

scope演算子は、列挙体内の列挙子にアクセスするためにオプションで使用できます。したがって、 enumName1は、 myEnum::enumName1綴りにすることもできます。

列挙子は、列挙体の各列挙子に対して0から始まり1ずつ増加する整数値が割り当てられます。したがって、上記の場合、 enumName1は値0を持ち、 enumName2は値1を持ちます。

列挙子には、ユーザーが特定の値を割り当てることもできます。この値は整数定数式でなければなりません。値が明示的に提供されていない列挙子の値は、以前の列挙子+ 1の値に設定されます。

enum myEnum
{
    enumName1 = 1, // value will be 1
    enumName2 = 2, // value will be 2
    enumName3,     // value will be 3, previous value + 1
    enumName4 = 7, // value will be 7
    enumName5,     // value will be 8
    enumName6 = 5, // value will be 5, legal to go backwards
    enumName7 = 3, // value will be 3, legal to reuse numbers
    enumName8 = enumName4 + 2, // value will be 9, legal to take prior enums and adjust them
};

switch文の列挙

列挙子の一般的な用途はswitch文のためであり、一般に状態マシンに現れる。実際、switch文の列挙型の便利な機能は、スイッチにデフォルトの文が含まれておらず、enumのすべての値が利用されていない場合、コンパイラが警告を出すということです。

enum State {
    start,
    middle,
    end
};

...

switch(myState) {
    case start:
       ...
    case middle:
       ...
} // warning: enumeration value 'end' not handled in switch [-Wswitch]

列挙型の繰り返し

エニュメレーションで反復処理する組み込み関数はありません。

しかし、いくつかの方法があります

  • 連続する値のみを持つenum場合:

    enum E {
        Begin,
        E1 = Begin,
        E2,
        // ..
        En,
        End
    };
    
    for (E e = E::Begin; e != E::End; ++e) {
        // Do job with e
    }
    
C ++ 11

enum classではoperator ++を実装する必要があります:

E& operator ++ (E& e)
{
    if (e == E::End) {
        throw std::out_of_range("for E& operator ++ (E&)");
    }
    e = E(static_cast<std::underlying_type<E>::type>(e) + 1);
    return e;
}
  • コンテナをstd::vectorとして使用する

    enum E {
        E1 = 4,
        E2 = 8,
        // ..
        En
    };
    
    std::vector<E> build_all_E()
    {
        const E all[] = {E1, E2, /*..*/ En};
        
        return std::vector<E>(all, all + sizeof(all) / sizeof(E));
    }
    
    std::vector<E> all_E = build_all_E();
    

    その後

    for (std::vector<E>::const_iterator it = all_E.begin(); it != all_E.end(); ++it) {
        E e = *it;
        // Do job with e;
    }
    
C ++ 11
  • またはstd::initializer_listと簡単な構文:

    enum E {
        E1 = 4,
        E2 = 8,
        // ..
        En
    };
    
    constexpr std::initializer_list<E> all_E = {E1, E2, /*..*/ En};
    

    その後

    for (auto e : all_E) {
        // Do job with e
    }
    

スコープ付き列挙型

C ++ 11ではスコープ付きenumとして知られているものを紹介しています。これらは、メンバーがenumname::membername修飾されなければならない列挙です。スコープ付き列挙型は、 enum class構文を使用して宣言されます。たとえば、虹の色を格納するには:

enum class rainbow {
    RED,
    ORANGE,
    YELLOW,
    GREEN,
    BLUE,
    INDIGO,
    VIOLET
};

特定の色にアクセスするには:

rainbow r = rainbow::INDIGO;

enum class 、キャストなしで暗黙的にint変換することはできません。したがってint x = rainbow::REDは無効です。

Scoped列挙では、メンバを表すのに使用されるである基になる型を指定することもできます。デフォルトではintです。 Tic-Tac-Toeゲームでは、その作品を

enum class piece : char {
    EMPTY = '\0',
    X = 'X',
    O = 'O',
};

enumのとおり、 enumは最後のメンバーの後にコンマをつけることができます。

C ++での列挙型宣言11

スコープ付き列挙型:

...
enum class Status; // Forward declaration 
Status doWork(); // Use the forward declaration
...
enum class Status { Invalid, Success, Fail };
Status doWork() // Full declaration required for implementation
{
    return Status::Success;
}    

未スコープの列挙型:

...
enum Status: int; // Forward declaration, explicit type required
Status doWork(); // Use the forward declaration
...
enum Status: int{ Invalid=0, Success, Fail }; // Must match forward declare type
static_assert( Success == 1 );

詳細なマルチファイルの例がここにあります: Blind fruit merchant example



Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow