wake-up-neo.net

Verwenden von Enum-In-Typen - Compiler-Warnung C4482 C++

Ich benutze den vollständig qualifizierten Namen der Aufzählung innerhalb einer Methode in einer meiner Klassen. Ich erhalte jedoch eine Compiler-Warnung, die "Warnung C4482: Nicht-Standarderweiterung verwendet: Aufzählung 'Foo' in qualifiziertem Namen verwendet". Müssen wir in C++ Enumerationen ohne den qualifizierten Namen verwenden? Aber IMO, das sieht hässlich aus. 

Irgendwelche Gedanken?

63
Navaneeth K N

Ja, Aufzählungen erstellen keinen neuen "Namespace", die Werte in der Aufzählung sind direkt im umgebenden Bereich verfügbar. So bekommst du:

enum sample {
  SAMPLE_ONE = 1,
  SAMPLE_TWO = 2
};

int main() {
  std::cout << "one = " << SAMPLE_ONE << std::endl;
  return 0;
}
58
sth

Um es sauber zu machen, ersetzen Sie:

enum Fruit {

    ORANGE = 0,
    BANANA = 1

};

mit

namespace Fruit {

    enum { //no enum name needed

        ORANGE = 0,
        BANANA = 1

    };

};

...

int f = Fruit::BANANA; //No warning
37
Poy

Während etw die Frage beantwortet, ging es nicht darum, wie ich immer Enummen verwendet habe. Obwohl es sich nur um mehr oder weniger Namen für Zahlen handelt, habe ich sie immer verwendet, um Typen zu definieren, die nur bestimmte Werte haben können.

Wenn die Aufzählung Teil der Klasse ist, hilft dies den Verbrauchern, eine Aufzählungsreferenz eindeutig zu identifizieren:

class Apple {
  enum Variety {
    Gala,
    GoldenDelicious,
    GrannySmith,
    Fuji
  }
  ...
};

Konsumenten könnten dann Instanzen der Aufzählung deklarieren, als Parameter übergeben und sie beim Referenzieren eines der Typen qualifizieren.

unsigned int GetCountOfApples( Apple::Variety appleVariety );
...
fujiCnt = GetCountOfApples( Apple::Fuji );

Manchmal möchten Sie eine Aufzählung außerhalb einer Klasse oder zwei Aufzählungen in derselben Klasse, und Sie können so etwas wie Poy tun. Sie können den Aufzählungstyp jedoch nicht referenzieren. Benennen Sie ihn einfach.

namespace Color {
  enum ColorEnum {
    Blue,
    Red,
    Black
  };

Nun würde die Verwendung der Enumeration und der Werte wie folgt funktionieren:

Color::ColorEnum firstColor = Color::Blue;
Color::ColorEnum secondColor = Color::Red;

if( firstColor == secondColor )
....

Wenn nun verschiedene Enumerationen mit demselben Namen in ihnen vorhanden sind, werden sie immer mit dem Typ qualifiziert, der sie sind. Dann könnten Sie damit umgehen, was der Spieler fragt.

BananaColorEnum banCol = BananaColor::Yellow;
TomatoColorEnum tomCol = TomatoColor::Yellow;
15
jmc

Ja. Konzeptuell definiert enum einen Typ und die möglichen Werte dieses Typs. Obwohl es natürlich erscheint, enum foo { bar, baz }; zu definieren und dann auf foo::baz zu verweisen, ist das Gleiche wie der Verweis auf 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

Dies funktioniert auf GCC und MS Compiler und Mac. Der Vorteil ist, dass Sie den Namespace-Operator verwenden und Konflikte weiterleiten können. Der kleine Nachteil ist, dass Sie anstelle von Fruit Fruit :: Value schreiben müssen. In großen Projekten ist es sinnvoller, wenn Sie nicht wissen, welche Enumerationen sich in einer anderen Klasse befinden.

Wenn stattdessen C++ 11 verwendet werden kann, ist dies viel einfacher, da dann die enum :: namespace-Syntax möglich ist.

8
Tomas Kubes

Die sauberste Methode, die ich dazu gefunden habe, ist das Definieren der Aufzählung als solche

namespace Samples
{
    enum Value
    {
        Sample1,
        Sample2,
        Sample3
    };
}
typedef Samples::Value Sample;

Dann können Sie in Funktions- und Variablendefinitionen die Typedef verwenden:

void Function(Sample eSample);
Sample m_eSample;

In Ihrer .cpp-Datei können Sie den Namespace verwenden, um Variablen zuzuweisen:

void Function(Sample eSample)
{
    m_eSample = Samples::Sample1;
    eSample = Samples::Sample2;
}
7
petejamd

Ich persönlich denke, dass dies ein Compiler-Fehler ist. Ich habe C++ schon lange verwendet. Leider kein Beispielcode in OP. Die Interpretation eines Enums durch die Java-Leute war eigentlich iMO. Meins war so ...

class Foo {
    enum tMyEnum { eFirstVal = 0, eSecondVal = 1};
    // ...
    tMyEnum m_myVal;
};
void Foo::MyMethod() {
    if(m_myVal == tMyEnum::eFirstVal) {
//  ...
    }
}

Ich habe auch versucht, Foo :: tMyEnum :: eFirstVal. Ohne die Qualifikanten wurde alles zusammengestellt.

1
georgejo

Ich hatte das gleiche Problem und verwende C++ 11 noch nicht. Ich persönlich bevorzuge voll qualifizierte Namespaces.

Ich habe diese Warnung deaktiviert. Ich bin mir sicher, dass die Leute die Idee nicht mögen werden, aber einige mögen dankbar sein ..

#pragma warning( disable : 4482 )
0
SparkyNZ