Comment utiliser les énumérations en C ++

Supposons que nous ayons une enum comme celle-ci:

 enum Days {Saturday, Sunday, Tuesday,Wednesday, Thursday, Friday}; 

Je veux créer une instance de cette enum et l’initialiser avec une valeur correcte, donc je fais:

 Days day = Days.Saturday; 

Maintenant, je veux vérifier ma variable ou mon instance avec une valeur enum existante, donc je fais:

 if (day == Days.Saturday) { std::cout<<"Ok its Saturday"; } 

Ce qui me donne une erreur de compilation:

erreur: expression primaire attendue avant ‘.’ jeton

Donc, pour être clair, quelle est la différence entre dire:

 if (day == Days.Saturday) //Causes compilation error 

et

 if (day == Saturday) 

?

À quoi ces deux références se réfèrent-elles, l’une étant OK et l’autre causant une erreur de compilation?

Ce code est faux:

 enum Days { Saturday,Sunday,Tuesday,Wednesday,Thursday,Friday}; Days day = Days.Saturday; if(day == Days.Saturday) 

Parce que les jours ne sont pas une scope, ni un object. C’est un type. Et les Types eux-mêmes n’ont pas de membres. Ce que vous avez écrit est l’équivalent de std::ssortingng.clear . std::ssortingng est un type, vous ne pouvez donc pas l’utiliser . dessus. Vous utilisez . sur une instance d’une classe.

Malheureusement, les énumérations sont magiques et l’analogie s’arrête là. Parce qu’avec une classe, vous pouvez faire std::ssortingng::clear pour obtenir un pointeur sur la fonction membre, mais en C ++ 03, Days::Sunday n’est pas valide. (Ce qui est sortingste). Cela est dû au fait que C ++ est (quelque peu) compatible avec C et que C n’a pas d’espace de noms, de sorte que les énumérations doivent se trouver dans l’espace de noms global. La syntaxe est donc simplement:

 enum Days { Saturday,Sunday,Tuesday,Wednesday,Thursday,Friday}; Days day = Saturday; if(day == Saturday) 

Heureusement, Mike Seymour observe que cela a été traité en C ++ 11. Changer enum en enum class et il a sa propre scope; so Days::Sunday est non seulement valide, mais est le seul moyen d’accéder au Sunday . Jours heureux!

Cela sera suffisant pour déclarer votre variable enum et la comparer:

 enum Days { Saturday,Sunday,Tuesday,Wednesday,Thursday,Friday}; Days day = Saturday; if(day == Saturday){ std::cout<<"Ok its Saturday"; } 

Une grande partie de cela devrait vous donner des erreurs de compilation.

 // note the lower case enum keyword enum Days { Saturday, Sunday, Monday, Tuesday, Wednesday, Thursday, Friday }; 

Maintenant, Saturday , Sunday , etc. peuvent être utilisés comme constantes nues de niveau supérieur, et les Days peuvent être utilisés comme un type:

 Days day = Saturday; // Days.Saturday is an error 

Et de même plus tard, pour tester:

 if (day == Saturday) // ... 

Ces valeurs d’ enum sont comme des constantes nues – elles sont non- scopées – avec un peu d’aide supplémentaire du compilateur: et vous ne pouvez pas les appeler membres de Days .

Vous aurez ce que vous cherchez avec C ++ 11 , qui introduit une enum class :

 enum class Days { SUNDAY, MONDAY, // ... etc. } // ... if (day == Days::SUNDAY) // ... 

Notez que ce C ++ est un peu différent de C de plusieurs manières, l’une étant que C nécessite l’utilisation du mot-clé enum lors de la déclaration d’une variable:

 // day declaration in C: enum Days day = Saturday; 

Vous pouvez utiliser une astuce pour utiliser les étendues comme vous le souhaitez, il vous suffit de déclarer le enum de la manière suivante:

 struct Days { enum type { Saturday,Sunday,Tuesday,Wednesday,Thursday,Friday }; }; Days::type day = Days::Saturday; if (day == Days::Saturday) 

Plutôt que d’utiliser une série de if-déclarations, les enums se prêtent bien au changement

J’utilise des combinaisons enum / switch dans le générateur de niveaux que je construis pour mon jeu.

EDIT: Une autre chose, je vois que vous voulez une syntaxe similaire à;

 if(day == Days.Saturday) etc 

Vous pouvez le faire en C ++:

 if(day == Days::Saturday) etc 

Voici un exemple très simple:

EnumAppState.h

 #ifndef ENUMAPPSTATE_H #define ENUMAPPSTATE_H enum eAppState { STARTUP, EDIT, ZONECREATION, SHUTDOWN, NOCHANGE }; #endif 

Somefile.cpp

 #include "EnumAppState.h" eAppState state = eAppState::STARTUP; switch(state) { case STARTUP: //Do stuff break; case EDIT: //Do stuff break; case ZONECREATION: //Do stuff break; case SHUTDOWN: //Do stuff break; case NOCHANGE: //Do stuff break; } 

Cela ne devrait pas fonctionner en C ++:

 Days.Saturday 

Days n’est pas une étendue ou un object contenant des membres auxquels vous pouvez accéder avec l’opérateur de points. Cette syntaxe est juste un C # -ism et n’est pas légale en C ++.

Microsoft a longtemps maintenu une extension C ++ qui vous permet d’accéder aux identificateurs à l’aide de l’opérateur de scope:

 enum E { A, B, C }; A; E::B; // works with Microsoft's extension 

Mais ce n’est pas standard avant C ++ 11. En C ++ 03, les identificateurs déclarés dans une énumération n’existent que dans la même scope que le type enum lui-même.

 A; E::B; // error in C++03 

C ++ 11 permet de qualifier les identifiants enum avec le nom enum, et introduit également les classes enum, qui créent une nouvelle scope pour les identificateurs au lieu de les placer dans la scope environnante.

 A; E::B; // legal in C++11 enum class F { A, B, C }; A; // error F::B; 

Malheureusement, les éléments de la liste sont «globaux». Vous y accédez en faisant day = Saturday . Cela signifie que vous ne pouvez pas avoir enum A { a, b } ; et enum B { b, a } ; car ils sont en conflit.

Les énumérations en C ++ sont comme des entiers masqués par les noms que vous leur donnez, lorsque vous déclarez vos valeurs d’énumération (ce n’est pas une définition, mais une indication de son fonctionnement).

Mais il y a deux erreurs dans votre code:

  1. Épeler enum toutes les minuscules
  2. Vous n’avez pas besoin des Days. avant samedi
  3. Si cette énumération est déclarée dans une classe, alors utilisez if (day == YourClass::Saturday){}

Alors que C ++ (à l’exclusion de C ++ 11) a des énumérations, les valeurs qui y figurent sont “fuites” dans l’espace de noms global.
Si vous ne voulez pas les faire fuir (et ne devez PAS utiliser le type enum), considérez les points suivants:

 class EnumName { public: static int EnumVal1; (more definitions) }; EnumName::EnumVal1 = {value}; if ([your value] == EnumName::EnumVal1) ... 

Vous recherchez des énumérations fortement typées , une fonctionnalité disponible dans la norme C ++ 11 . Il transforme les énumérations en classes avec des valeurs de scope.

En utilisant votre propre exemple de code, c’est:

  enum Days {Saturday, Sunday, Tuesday,Wednesday, Thursday, Friday}; Days day = Days::Saturday; if (day == Days::Saturday) { cout<<" Today is Saturday !"< 

L'utilisation de :: as comme accesseurs aux énumérations échouera si vous ciblez un standard C ++ antérieur à C ++ 11. Mais certains anciens compilateurs ne le supportent pas, de même que certains IDE ne remplacent que cette option et définissent un ancien std C ++.

Si vous utilisez gcc, activez C + 11 avec -std = c ++ 11 ou -std = gnu11 .

Soyez heureux !

Si vous utilisez toujours C ++ 03 et souhaitez utiliser des énumérations, vous devriez utiliser des énumérations dans un espace de noms. Par exemple:

 namespace Daysofweek{ enum Days {Saturday, Sunday, Tuesday,Wednesday, Thursday, Friday}; } 

Vous pouvez utiliser l’énumération en dehors de l’espace de nommage comme,

 Daysofweek::Days day = Daysofweek::Saturday; if (day == Daysofweek::Saturday) { std::cout<<"Ok its Saturday"; } 

Je pense que votre problème fondamental est l’utilisation de . au lieu de :: , qui utilisera l’espace de noms.

Essayer:

 enum Days {Saturday, Sunday, Tuesday, Wednesday, Thursday, Friday}; Days day = Days::Saturday; if(Days::Saturday == day) // I like literals before variables :) { std::cout<<"Ok its Saturday"; } 

Tout d’abord, faites «E» en enum, «e» en minuscule.

Deuxièmement, supprimez le nom de type «Days» dans «Days.Saturday».

Troisièmement, achetez-vous un bon livre en C ++.