Supposons que nous ayons une enum
semblable à celle-ci:
enum Days {Saturday, Sunday, Tuesday,Wednesday, Thursday, Friday};
Je veux créer une instance de ce enum
et l'initialiser avec une valeur appropriée. Je fais donc:
Days day = Days.Saturday;
Maintenant, je veux vérifier ma variable ou instance avec une valeur existante enum
, alors je le fais:
if (day == Days.Saturday)
{
std::cout<<"Ok its Saturday";
}
Ce qui me donne une erreur de compilation:
erreur: expression primaire attendue avant le 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-là font-ils réellement référence, dans la mesure où l'un est OK et l'autre provoque 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 Days
n'est ni une portée, ni un objet. C'est un type. Et les types eux-mêmes n'ont pas de membres. Ce que vous avez écrit équivaut à std::string.clear
. std::string
est un type, vous ne pouvez donc pas utiliser .
dessus. Vous utilisez .
sur une instance d'une classe.
Malheureusement, les enums sont magiques et l'analogie s'arrête là. Parce qu'avec une classe, vous pouvez utiliser std::string::clear
pour obtenir un pointeur sur la fonction membre, mais en C++ 03, Days::Sunday
n'est pas valide. (Ce qui est triste). Cela est dû au fait que C++ est (quelque peu) rétro-compatible avec C, et que C n’avait pas d’espaces de noms, les énumérations devaient donc se trouver dans l’espace de noms global. Donc, la syntaxe est 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. Remplacez enum
par enum class
et il aura sa propre portée. so Days::Sunday
est non seulement valide, mais constitue le moyen uniquement d'accéder à 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 ceci 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 en tant que constantes nues de niveau supérieur, et Days
peut être utilisé en tant que type:
Days day = Saturday; // Days.Saturday is an error
Et pareillement plus tard, pour tester:
if (day == Saturday)
// ...
Ces valeurs enum
ressemblent à des constantes nues - elles sont un - scoped - avec un peu d'aide supplémentaire du compilateur: (sauf si vous ' En utilisant C++ 11 les classes enum ) elles ne sont pas encapsulées comme les membres d'objet ou de structure, par exemple, et vous ne pouvez pas les appeler membres de Days
.
Vous aurez ce que vous cherchez avec C++ 11 , qui introduit un enum class
:
enum class Days
{
SUNDAY,
MONDAY,
// ... etc.
}
// ...
if (day == Days::SUNDAY)
// ...
Notez que ce C++ est un peu différent du C de plusieurs façons. L'un d'entre eux est que C requiert 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 portées à votre guise, déclarez simplement 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 un ensemble d’énoncés if, les enums se prêtent bien pour changer de déclaration
J'utilise des combinaisons enum/switch dans le générateur de niveau 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;
}
Si vous utilisez encore C++ 03 et souhaitez utiliser des énumérations, vous devriez les utiliser à l'intérieur d'un espace de noms. Par exemple:
namespace Daysofweek{
enum Days {Saturday, Sunday, Tuesday,Wednesday, Thursday, Friday};
}
Vous pouvez utiliser l'énum en dehors de l'espace de noms comme,
Daysofweek::Days day = Daysofweek::Saturday;
if (day == Daysofweek::Saturday)
{
std::cout<<"Ok its Saturday";
}
Cela ne devrait pas fonctionner en C++:
Days.Saturday
Jours n'est pas une étendue ou un objet contenant des membres auxquels vous pouvez accéder avec l'opérateur point. 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 identifiants à l'aide de l'opérateur de portée:
enum E { A, B, C };
A;
E::B; // works with Microsoft's extension
Mais ceci est non standard avant C++ 11. En C++ 03, les identificateurs déclarés dans une énumération n'existent que dans la même portée que le type énuméré lui-même.
A;
E::B; // error in C++03
C++ 11 permet de qualifier les identificateurs enum avec le nom enum, et introduit également les classes enum, qui créent une nouvelle portée pour les identificateurs au lieu de les placer dans la portée environnante.
A;
E::B; // legal in C++11
enum class F { A, B, C };
A; // error
F::B;
Vous recherchez Énumérations fortement typées , une fonctionnalité disponible en C++ 11 standard. Il transforme les énumérations en classes avec des valeurs de portée.
En utilisant votre propre exemple de code, il est:
enum class Days {Saturday, Sunday, Tuesday,Wednesday, Thursday, Friday};
Days day = Days::Saturday;
if (day == Days::Saturday) {
cout<<" Today is Saturday !"<<endl;
}
//int day2 = Days::Sunday; // error ! invalid
L'utilisation de ::
comme accesseurs d'énumérations échouera si la cible est une norme C++ antérieure à C++ 11. Mais certains anciens compilateurs ne le supportaient pas, de même que certains IDE surchargent simplement cette option et définissent un ancien C++ std.
Si vous utilisez gcc, activez C + 11 avec - std = c ++ 11 ou - std = gnu11.
Soyez heureux !
Les énumérations en C++ sont comme des entiers masqués par les noms que vous leur donnez, lorsque vous déclarez vos valeurs enum (ce n'est pas une définition, mais un indice sur son fonctionnement).
Mais il y a deux erreurs dans votre code:
enum
tout en minusculeDays.
avant samedi.if (day == YourClass::Saturday){}
Malheureusement, les éléments de l'énum 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.
Tandis que C++ (à l'exception de C++ 11) a des énumérations, leurs valeurs sont "filtrées" dans l'espace de noms global.
Si vous ne voulez pas qu’ils fuient (et n’avez PAS besoin d’utiliser le type enum), tenez compte des points suivants:
class EnumName {
public:
static int EnumVal1;
(more definitions)
};
EnumName::EnumVal1 = {value};
if ([your value] == EnumName::EnumVal1) ...
Je pense que votre problème fondamental est l'utilisation de .
à la place 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";
}