J'utilise le nom complet de l'énum dans une méthode de l'une de mes classes. Mais je reçois un avertissement du compilateur qui indique "un avertissement C4482: extension non standard utilisée: enum 'Foo' utilisée sous un nom qualifié" . En C++, devons-nous utiliser des énumérations sans nom qualifié? Mais IMO, ça a l'air moche.
Des pensées?
Oui, les enums ne créent pas de nouvel "espace de noms", les valeurs de l'énum sont directement disponibles dans la portée environnante Donc vous obtenez:
enum sample {
SAMPLE_ONE = 1,
SAMPLE_TWO = 2
};
int main() {
std::cout << "one = " << SAMPLE_ONE << std::endl;
return 0;
}
Pour le rendre propre, remplacez:
enum Fruit {
ORANGE = 0,
BANANA = 1
};
avec
namespace Fruit {
enum { //no enum name needed
ORANGE = 0,
BANANA = 1
};
};
...
int f = Fruit::BANANA; //No warning
Bien que sth réponde à la question, cela ne dit pas comment j'ai toujours utilisé des énums. Même si ce sont juste plus ou moins de noms pour les nombres, je les ai toujours utilisés pour définir des types qui ne peuvent avoir que certaines valeurs.
Si l'énumération fait partie de la classe, cela aide les consommateurs à identifier clairement une référence d'énumération:
class Apple {
enum Variety {
Gala,
GoldenDelicious,
GrannySmith,
Fuji
}
...
};
Les consommateurs pourront alors déclarer des instances de l’énumération, les passer en tant que paramètres et les qualifier lors de la référence à l’un des types.
unsigned int GetCountOfApples( Apple::Variety appleVariety );
...
fujiCnt = GetCountOfApples( Apple::Fuji );
Parfois, vous voulez une énumération en dehors d’une classe ou deux énumérations de la même classe, et vous pouvez faire quelque chose comme Poy. Cependant, vous ne pourrez pas référencer le type enum, donc nommez-le.
namespace Color {
enum ColorEnum {
Blue,
Red,
Black
};
Maintenant, en utilisant l'énumération et les valeurs fonctionneraient comme ceci:
Color::ColorEnum firstColor = Color::Blue;
Color::ColorEnum secondColor = Color::Red;
if( firstColor == secondColor )
....
Maintenant, s'il se trouve qu'il y a différentes énumérations portant le même nom, elles seront toujours qualifiées avec leur type. Ensuite, vous pouvez gérer ce que le joueur demande.
BananaColorEnum banCol = BananaColor::Yellow;
TomatoColorEnum tomCol = TomatoColor::Yellow;
Oui. Conceptuellement, enum définit un type et les valeurs possibles de ce type. Même si cela semble naturel, définir enum foo { bar, baz };
et ensuite se référer à foo::baz
revient à faire référence à int::1
namespace Company
{
typedef int Value;
enum
{
Microsoft= 0,
Apple = 1,
};
};
namespace Fruit
{
typedef int Value;
enum
{
ORANGE = 0,
BANANA = 1,
Apple = 2,
};
};
...
Fruit::Value f = Fruit::BANANA; //No warning
Company::Value f = Company::Apple; //is different value then Fruit::Apple
Cela fonctionne sur le compilateur GCC, MS et Mac. Et l'avantage est que vous pouvez utiliser l'opérateur d'espace de noms et résoudre les conflits. Le petit inconvénient est qu'au lieu de Fruit, vous devez écrire Fruit :: Value. c'est plus utile dans un grand projet quand vous ne savez pas ce qui est enums dans une autre classe.
S'il est possible d'utiliser C++ 11 à la place, c'est beaucoup plus simple, car la syntaxe enum :: namespace est alors possible.
La façon la plus propre que j'ai trouvée est de définir l'énum en tant que tel
namespace Samples
{
enum Value
{
Sample1,
Sample2,
Sample3
};
}
typedef Samples::Value Sample;
Ensuite, dans les définitions de fonction et de variable, vous pouvez utiliser le typedef:
void Function(Sample eSample);
Sample m_eSample;
Et dans votre fichier .cpp, vous pouvez utiliser l’espace de noms pour attribuer des variables:
void Function(Sample eSample)
{
m_eSample = Samples::Sample1;
eSample = Samples::Sample2;
}
Personnellement, je pense que c'est un bug du compilateur. J'utilise C++ depuis beaucoup de temps. Malheureusement, aucun exemple de code dans OP. L'interprétation d'une enum par le peuple Java était en fait correcte iMO. La mienne était comme ça ...
class Foo {
enum tMyEnum { eFirstVal = 0, eSecondVal = 1};
// ...
tMyEnum m_myVal;
};
void Foo::MyMethod() {
if(m_myVal == tMyEnum::eFirstVal) {
// ...
}
}
J'ai aussi essayé, Foo :: tMyEnum :: eFirstVal. Sans les qualificatifs, tout est compilé.
J'ai eu le même problème et je n'utilise pas encore C++ 11. Moi aussi, je préfère de loin les espaces de noms pleinement qualifiés.
J'ai désactivé cet avertissement particulier. Je suis sûr que les gens n'aimeront pas l'idée, mais certains peuvent être reconnaissants ..
#pragma warning( disable : 4482 )