C++
Enumeración
Buscar..
Declaración de enumeración básica
Las enumeraciones estándar permiten a los usuarios declarar un nombre útil para un conjunto de enteros. Los nombres se conocen colectivamente como enumeradores. Una enumeración y sus enumeradores asociados se definen de la siguiente manera:
enum myEnum
{
enumName1,
enumName2,
};
Una enumeración es un tipo , uno que es distinto de todos los otros tipos. En este caso, el nombre de este tipo es myEnum
. Se espera que los objetos de este tipo asuman el valor de un enumerador dentro de la enumeración.
Los enumeradores declarados dentro de la enumeración son valores constantes del tipo de enumeración. Aunque los enumeradores están declarados dentro del tipo, el operador de alcance ::
no es necesario para acceder al nombre. Entonces el nombre del primer enumerador es enumName1
.
El operador de alcance se puede usar opcionalmente para acceder a un enumerador dentro de una enumeración. Así que enumName1
también se puede deletrear myEnum::enumName1
.
A los enumeradores se les asignan valores enteros que comienzan desde 0 y aumentan en 1 para cada enumerador en una enumeración. Entonces, en el caso anterior, enumName1
tiene el valor 0, mientras que enumName2
tiene el valor 1.
Los usuarios también pueden asignar un valor específico al usuario; este valor debe ser una expresión constante constante. Los enumeradores cuyos valores no se proporcionan explícitamente tendrán su valor establecido en el valor del enumerador anterior + 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
};
Enumeración en declaraciones de cambio
Un uso común para los enumeradores es para las declaraciones de cambio y, por lo tanto, suelen aparecer en las máquinas de estado. De hecho, una característica útil de las declaraciones de cambio con enumeraciones es que si no se incluye una declaración predeterminada para el cambio, y no se han utilizado todos los valores de la enumeración, el compilador emitirá una advertencia.
enum State {
start,
middle,
end
};
...
switch(myState) {
case start:
...
case middle:
...
} // warning: enumeration value 'end' not handled in switch [-Wswitch]
Iteración sobre una enumeración
No hay una función para iterar sobre la enumeración.
Pero hay varias formas
para la
enum
con solo valores consecutivos: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
, el operator ++
tiene que ser implementado:
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 contenedor como
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();
y entonces
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
y una sintaxis más simple:enum E { E1 = 4, E2 = 8, // .. En }; constexpr std::initializer_list<E> all_E = {E1, E2, /*..*/ En};
y entonces
for (auto e : all_E) { // Do job with e }
Enumerados con alcance
C ++ 11 introduce lo que se conoce como enumeraciones de ámbito . Estas son enumeraciones cuyos miembros deben ser calificados con enumname::membername
. Las enums con alcance se declaran usando la sintaxis de enum class
. Por ejemplo, para almacenar los colores en un arco iris:
enum class rainbow {
RED,
ORANGE,
YELLOW,
GREEN,
BLUE,
INDIGO,
VIOLET
};
Para acceder a un color específico:
rainbow r = rainbow::INDIGO;
enum class
no se pueden convertir implícitamente a int
s sin una conversión. Así que int x = rainbow::RED
no es válido.
Los enums con ámbito también le permiten especificar el tipo subyacente , que es el tipo utilizado para representar a un miembro. Por defecto es int
. En un juego de Tic-Tac-Toe, puedes guardar la pieza como
enum class piece : char {
EMPTY = '\0',
X = 'X',
O = 'O',
};
Como puede observar, las enum
pueden tener una coma final después del último miembro.
Enumerar la declaración hacia adelante en C ++ 11
Enumeración de ámbito:
...
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;
}
Enumeración sin ámbito:
...
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 );
Puede encontrar un ejemplo detallado de archivos múltiples aquí: Ejemplo de comerciante de frutas ciegas