C++
Énumération
Recherche…
Déclaration de dénombrement de base
Les énumérations standard permettent aux utilisateurs de déclarer un nom utile pour un ensemble d'entiers. Les noms sont collectivement appelés énumérateurs. Une énumération et ses énumérateurs associés sont définis comme suit:
enum myEnum
{
enumName1,
enumName2,
};
Une énumération est un type , qui est distinct de tous les autres types. Dans ce cas, le nom de ce type est myEnum
. Les objets de ce type sont censés prendre la valeur d'un énumérateur dans l'énumération.
Les énumérateurs déclarés dans l'énumération sont des valeurs constantes du type de l'énumération. Bien que les énumérateurs soient déclarés dans le type, l'opérateur d'étendue ::
n'est pas nécessaire pour accéder au nom. Le nom du premier énumérateur est donc enumName1
.
L'opérateur d'étendue peut éventuellement être utilisé pour accéder à un énumérateur dans une énumération. Donc, enumName1
peut également être orthographié myEnum::enumName1
.
Les énumérateurs se voient attribuer des valeurs entières commençant à 0 et augmentant de 1 pour chaque énumérateur dans une énumération. Donc, dans le cas ci-dessus, enumName1
a la valeur 0, alors que enumName2
a la valeur 1.
Les énumérateurs peuvent également se voir attribuer une valeur spécifique par l'utilisateur. cette valeur doit être une expression constante intégrale. Les énumérateurs dont les valeurs ne sont pas explicitement fournies auront leur valeur définie sur la valeur de l'énumérateur précédent + 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
};
Enumération dans les instructions de commutateur
Les énumérateurs sont couramment utilisés pour les instructions de commutation et apparaissent donc généralement dans les machines à états. En fait, une caractéristique utile des instructions de commutation avec énumérations est que si aucune instruction par défaut n'est incluse pour le commutateur et que toutes les valeurs de l'énumération n'ont pas été utilisées, le compilateur émettra un avertissement.
enum State {
start,
middle,
end
};
...
switch(myState) {
case start:
...
case middle:
...
} // warning: enumeration value 'end' not handled in switch [-Wswitch]
Itération sur un enum
Il n'y a pas d'itéré pour itérer l'énumération.
Mais il y a plusieurs façons
pour
enum
avec uniquement des valeurs consécutives:enum E { Begin, E1 = Begin, E2, // .. En, End }; for (E e = E::Begin; e != E::End; ++e) { // Do job with e }
avec la enum class
, operator ++
doit être implémenté:
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;
}
en utilisant un conteneur en tant que
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();
et alors
for (std::vector<E>::const_iterator it = all_E.begin(); it != all_E.end(); ++it) { E e = *it; // Do job with e; }
ou
std::initializer_list
et une syntaxe plus simple:enum E { E1 = 4, E2 = 8, // .. En }; constexpr std::initializer_list<E> all_E = {E1, E2, /*..*/ En};
et alors
for (auto e : all_E) { // Do job with e }
Énumérés
C ++ 11 introduit ce que l'on appelle les énumérations de portée . Ce sont des énumérations dont les membres doivent être qualifiés avec enumname::membername
. Les énumérations de portée sont déclarées en utilisant la syntaxe de la enum class
. Par exemple, pour stocker les couleurs dans un arc-en-ciel:
enum class rainbow {
RED,
ORANGE,
YELLOW,
GREEN,
BLUE,
INDIGO,
VIOLET
};
Pour accéder à une couleur spécifique:
rainbow r = rainbow::INDIGO;
enum class
es ne peuvent pas être implicitement converties en int
s sans conversion. Donc int x = rainbow::RED
n'est pas valide.
Les énumérations de portée vous permettent également de spécifier le type sous - jacent , qui est le type utilisé pour représenter un membre. Par défaut, il est int
. Dans un jeu Tic-Tac-Toe, vous pouvez stocker la pièce comme
enum class piece : char {
EMPTY = '\0',
X = 'X',
O = 'O',
};
Comme vous pouvez le constater, enum
s peut avoir une virgule après le dernier membre.
Énumérer la déclaration en avant en C ++ 11
Énumérations de portée:
...
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;
}
Énumérations non découpées:
...
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 exemple détaillé de fichiers multiples peut être trouvé ici: Exemple de marchand de fruits à l'aveugle