ProgrammazioneSenior C++ Developer

Parlate del meccanismo 'enum class' (scoped enums) in C++. Come si differenzia dalle normali enumerazioni e perché è stato introdotto? Quali errori sono tipici nel passaggio da vecchie enum a enum class?

Supera i colloqui con l'assistente IA Hintsage

Risposta

In C++11 è stato introdotto il meccanismo 'scoped enums' — la parola chiave enum class.

Principali differenze dalle enum classiche:

  • Il contenuto di enum class ha il proprio ambito di visibilità (scope), non inquina lo spazio dei nomi globale.
  • Non avviene una conversione implicita degli enumeratori a int (è necessaria una conversione esplicita).
  • Il tipo di enum class per default è: int, ma è possibile specificarne un altro (ad esempio, enum class MyE : uint8_t { ... };).

Perché è utile: Maggiore sicurezza dei tipi, prevenzione dei conflitti di nomi, confronti errati e gestione esplicita dello storage.

Esempio:

enum Color { Red, Green }; Color c = Red; // Enum normale, Red è visibile globalmente enum class State { Off, On }; State s = State::On; // È necessario specificare State::On

Non si può scrivere:

enum class State { Off, On }; int x = State::On; // Errore! Solo con cast int y = static_cast<int>(State::Off); // OK

Domanda trabocchetto

Perché non si può fare un confronto logico tra valori di diverse enum class, anche se coincidono nei nomi e nel tipo sottostante?

Risposta:

Sicurezza di tipo: ogni enum class è un tipo separato, anche se il tipo sottostante è lo stesso e gli enumeratori coincidono nei nomi. Il compilatore li percepirà come tipi diversi e non consentirà comparazioni implicite.

Esempi di errori reali a causa della mancanza di conoscenza dei dettagli.


Storia

Passando da enum a enum class in un progetto di controllo macchine, si è dimenticato di aggiungere la conversione esplicita durante l'output dei valori nei log. I log hanno iniziato a mostrare valori "estranei" (non riconoscevano State::On come numero), complicando il debug.


Storia

In un servizio REST, dopo la migrazione da enum normale a enum class, il codice confrontava valori di diverse enumerazioni da diversi enum class. Il compilatore non lo consentiva, i test automatici hanno smesso di compilarsi.


Storia

Nel sistema di audit, gli sviluppatori confondevano la sintassi vecchia e nuova — a volte dichiaravano accidentalmente enum class, ma usavano gli enumeratori senza qualificatore, di conseguenza il codice compilato non era quello giusto o si verificavano errori di linking a causa di nomi coincidenti.