C++
Enumerazione
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
.
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 }
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; }
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