Le classi enum ("nuovi enumerazioni", "enums forti") affrontano tre problemi con le enumerazioni tradizionali C++:
- convenzionale
enums
convertire implicitamente a int
, causando errori quando qualcuno non vuole un enumerazione di agire come un intero.
- convenzionale
enums
esportare i relativi enumeratori nell'ambiente circostante, causando conflitti di nomi.
- Il tipo sottostante di
enum
non può essere specificato, causando confusione, problemi di compatibilità e rende impossibile la dichiarazione diretta.
enum class
("enumerazioni forti") sono fortemente tipizzati e scope:
enum Alert { green, yellow, orange, red }; // traditional enum
enum class Color { red, blue }; // scoped and strongly typed enum
// no export of enumerator names into enclosing scope
// no implicit conversion to int
enum class TrafficLight { red, yellow, green };
Alert a = 7; // error (as ever in C++)
Color c = 7; // error: no int->Color conversion
int a2 = red; // ok: Alert->int conversion
int a3 = Alert::red; // error in C++98; ok in C++11
int a4 = blue; // error: blue not in scope
int a5 = Color::blue; // error: not Color->int conversion
Color a6 = Color::blue; // ok
Come mostrato, enumerazioni tradizionali funzionano come al solito, ma ora è possibile opzionalmente qualificare con il nome del enum.
Le nuove enumerazioni sono "enumerate" perché combinano aspetti delle enumerazioni tradizionali (valori dei nomi) con aspetti delle classi (membri dell'ambito e assenza di conversioni).
Essere in grado di specificare il tipo di fondo permettono più semplice l'interoperabilità e le dimensioni garantiti di enumerazioni:
enum class Color : char { red, blue }; // compact representation
enum class TrafficLight { red, yellow, green }; // by default, the underlying type is int
enum E { E1 = 1, E2 = 2, Ebig = 0xFFFFFFF0U }; // how big is an E?
// (whatever the old rules say;
// i.e. "implementation defined")
enum EE : unsigned long { EE1 = 1, EE2 = 2, EEbig = 0xFFFFFFF0U }; // now we can be specific
Consente inoltre dichiarazione anticipata di enumerazioni:
enum class Color_code : char; // (forward) declaration
void foobar(Color_code* p); // use of forward declaration
// ...
enum class Color_code : char { red, yellow, green, blue }; // definition
Il tipo di fondo deve essere uno dei tipi di interi con segno o senza segno; il valore predefinito è int
.
nella libreria standard, enum
classi sono utilizzate per: specifici codici di errore
- sistemi di mappatura: In
<system_error>
: enum class errc
; indicatori di sicurezza
- Pointer: In
<memory>
: enum class pointer_safety { relaxed, preferred, strict };
- errori I/O stream: In
<iosfwd>
: enum class io_errc { stream = 1 };
- comunicazioni asincrone di gestione degli errori: In
<future>
: enum class future_errc { broken_promise, future_already_retrieved, promise_already_satisfied };
Molti di questi sono operatori, come ad esempio ==
definito.
Hai dato un'occhiata a [wikipedia] (http://en.wikipedia.org/wiki/C%2B%2B11#Strongly_typed_enumerations)? – Nobody
@Nobody: Sì, ho visto 'wiki', ma non sono riuscito a capire come usarlo e quali sono i vantaggi. –