Ricerca…


Dichiarazione di enumerazione di base

Le enumerazioni standard consentono agli utenti di dichiarare un nome utile per un insieme di numeri interi. I nomi sono indicati collettivamente come enumeratori. Un'enumerazione e i relativi enumeratori associati sono definiti come segue:

enum myEnum
{
    enumName1,
    enumName2,
};

Un'enumerazione è un tipo , distinto da tutti gli altri tipi. In questo caso, il nome di questo tipo è myEnum . Ci si aspetta che oggetti di questo tipo assumano il valore di un enumeratore all'interno dell'enumerazione.

Gli enumeratori dichiarati all'interno dell'enumerazione sono valori costanti del tipo dell'enumerazione. Sebbene gli enumeratori siano dichiarati all'interno del tipo, l'operatore scope :: non è necessario per accedere al nome. Quindi il nome del primo enumeratore è enumName1 .

C ++ 11

L'operatore dell'ambito può essere facoltativamente utilizzato per accedere a un enumeratore all'interno di un'enumerazione. Quindi enumName1 può anche essere scritto myEnum::enumName1 .

Agli enumeratori vengono assegnati valori interi che iniziano da 0 e aumentano di 1 per ciascun enumeratore in un'enumerazione. Quindi, nel caso precedente, enumName1 ha il valore 0, mentre enumName2 ha il valore 1.

Agli enumeratori può anche essere assegnato un valore specifico dall'utente; questo valore deve essere un'espressione costante integrale. Gli enumeratori i cui valori non sono esplicitamente forniti avranno il loro valore impostato sul valore dell'enumeratore precedente + 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
};

Enumerazione nelle istruzioni switch

Un uso comune per gli enumeratori è per le istruzioni switch e quindi vengono comunemente visualizzati nelle macchine a stati. Infatti, una caratteristica utile delle istruzioni switch con enumerazioni è che se non è inclusa alcuna istruzione predefinita per lo switch e non tutti i valori dell'enumerazione sono stati utilizzati, il compilatore emetterà un avviso.

enum State {
    start,
    middle,
    end
};

...

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

Iterazione su un enum

Non esiste un built-in per iterare sull'enumerazione.

Ma ci sono diversi modi

  • per enum con solo valori consecutivi:

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

con la enum class , l' operator ++ deve essere implementato:

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;
}
  • usando un contenitore come 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();
    

    e poi

    for (std::vector<E>::const_iterator it = all_E.begin(); it != all_E.end(); ++it) {
        E e = *it;
        // Do job with e;
    }
    
C ++ 11
  • o std::initializer_list e una sintassi più semplice:

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

    e poi

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

Enumerazioni enunciate

C ++ 11 introduce quelli che sono noti come enumerati . Queste sono enumerazioni i cui membri devono essere qualificati con enumname::membername . Le enumerazioni scopate vengono dichiarate usando la sintassi della enum class . Ad esempio, per memorizzare i colori in un arcobaleno:

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

Per accedere a un colore specifico:

rainbow r = rainbow::INDIGO;

enum class non possono essere convertite implicitamente in int s senza un cast. Quindi int x = rainbow::RED non è valido.

Le enumerazioni scopate consentono inoltre di specificare il tipo sottostante , che è il tipo utilizzato per rappresentare un membro. Di default è int . In un gioco Tic-Tac-Toe, puoi memorizzare il pezzo come

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

Come puoi notare, enum s può avere una virgola finale dopo l'ultimo membro.

Dichiarazione anticipata Enum in C ++ 11

Enumerazioni scopate:

...
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;
}    

Enumerazioni senza ambito:

...
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 );

Un esempio dettagliato di file multipli può essere trovato qui: Esempio di mercante di frutta cieca



Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow