web-dev-qa-db-fra.com

Utiliser enum à l'intérieur des types - Avertissement du compilateur C4482 C++

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?

63
Navaneeth K N

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;
}
58
sth

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
37
Poy

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;
15
jmc

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 

11
Rob K

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.

8
Tomas Kubes

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;
}
7
petejamd

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é.

1
georgejo

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 )
0
SparkyNZ