En C++11 se introdujo el mecanismo 'enumeraciones con ámbito' — la palabra clave enum class.
Principales diferencias con las enum clásicas:
enum class MyE : uint8_t { ... };).¿Para qué sirve? Para aumentar la seguridad de tipos, prevenir conflictos de nombres, comparaciones erróneas y gestionar explícitamente el almacenamiento.
Ejemplo:
enum Color { Rojo, Verde }; Color c = Rojo; // Enum normal, Rojo es visible globalmente enum class State { Apagado, Encendido }; State s = State::Encendido; // Necesita especificar State::Encendido
No se puede escribir:
enum class State { Apagado, Encendido }; int x = State::Encendido; // ¡Error! Solo con cast int y = static_cast<int>(State::Apagado); // OK
¿Por qué no se puede hacer una comparación lógica entre valores de diferentes enum class, incluso si coinciden en nombres y tipo subyacente?
Respuesta:
Seguridad de tipos: cada enum class es un tipo separado, incluso si el tipo subyacente es el mismo y los enumeradores coinciden en nombres. El compilador los considerará tipos diferentes y no permitirá comparación implícita.
Historia
Al pasar de enum a enum class en un proyecto de control de máquinas, olvidaron agregar la conversión explícita al mostrar valores en el registro. Los registros comenzaron a mostrar valores "extranjeros" (no reconocían State::Encendido como un número), lo que complicó la depuración.
Historia
En un servicio REST después de la migración de enum normal a enum class, el código comparaba valores de diferentes enumeraciones de diferentes enum class. El compilador no permitió esto, y las pruebas automáticas dejaron de compilar.
Historia
En un sistema de auditoría, los desarrolladores confundieron la sintaxis antigua y nueva; a veces declaraban erróneamente un enum class, pero usaban enumeradores sin calificador, resultando en la compilación de un código incorrecto o errores de vinculación debido a nombres coincidentes.