Angenommen, wir haben enum
Folgendes:
enum Days {Saturday, Sunday, Tuesday, Wednesday, Thursday, Friday};
Ich möchte eine Instanz davon erstellen enum
und sie mit einem geeigneten Wert initialisieren, also mache ich:
Days day = Days.Saturday;
Jetzt möchte ich meine Variable oder Instanz mit einem vorhandenen enum
Wert überprüfen , also mache ich:
if (day == Days.Saturday)
{
std::cout << "Ok its Saturday";
}
Was mir einen Kompilierungsfehler gibt:
Fehler: erwarteter primärer Ausdruck vor '.' Zeichen
Um klar zu sein, was ist der Unterschied zwischen den Worten:
if (day == Days.Saturday) // Causes compilation error
und
if (day == Saturday)
?
Worauf beziehen sich diese beiden eigentlich, da einer in Ordnung ist und einer einen Kompilierungsfehler verursacht?
Antworten:
Dieser Code ist falsch:
Weil
Days
es weder ein Bereich noch ein Objekt ist. Es ist ein Typ. Und Typen selbst haben keine Mitglieder. Was Sie geschrieben haben, entsprichtstd::string.clear
.std::string
ist ein Typ, den Sie nicht verwenden.
können. Sie verwenden.
für eine Instanz einer Klasse.Leider sind Aufzählungen magisch und so hört die Analogie hier auf. Denn mit einer Klasse können Sie
std::string::clear
einen Zeiger auf die Member-Funktion abrufen, der in C ++ 03Days::Sunday
jedoch ungültig ist. (Was traurig ist). Dies liegt daran, dass C ++ (etwas) abwärtskompatibel mit C ist und C keine Namespaces hatte, sodass Aufzählungen im globalen Namespace sein mussten. Die Syntax lautet also einfach:Glücklicherweise stellt Mike Seymour fest , dass dies in C ++ 11 behoben wurde. Wechseln Sie
enum
zuenum class
und es bekommt seinen eigenen Umfang; DiesDays::Sunday
ist nicht nur gültig, sondern auch die einzige Möglichkeit, darauf zuzugreifenSunday
. Glückliche Tage!quelle
enum
zuenum class
und es bekommt seinen eigenen Umfang; DiesDays::Sunday
ist nicht nur gültig, sondern auch die einzige Möglichkeit, darauf zuzugreifenSunday
. Glückliche Tage!'.' token
unddot operator
, außer es ist ein Token und kein Operator, und es zeigt das genaue Symbol und nicht einen Namen.enum
, können Sie keinen Bereich oder den globalen Bereich (::Saturday
) verwenden. Wenn Sie eine habenenum class
(das ist eine ganz andere Sache ist), dann Sie haben zu verwendenDays::Saturday
.Dies reicht aus, um Ihre Enum-Variable zu deklarieren und zu vergleichen:
quelle
Days
es weder ein Bereich noch ein Objekt ist. Es ist ein Typ. Und Typen selbst haben keine Mitglieder.std::string.clear
kann aus dem gleichen Grund auch nicht kompiliert werden.enum class
neu in 2011) haben einen eigenen Bereich und werden über den Bereichsoperator aufgerufenDays::Saturday
. Der Member Access Operator (.
) wird nur für den Zugriff auf Klassenmitglieder verwendet.Vieles davon sollte zu Kompilierungsfehlern führen.
Nun
Saturday
,Sunday
usw. können als Top-Level - bare Konstanten verwendet werden, undDays
kann als eine Art verwendet werden:Und ähnlich später, um zu testen:
Diese
enum
Werte sind wie nackte Konstanten - sie sind un -scoped - mit ein wenig mehr Hilfe vom Compiler: (es sei denn , Sie verwenden C ++ 11 Enum - Klassen ) sie sind nicht wie Objekt oder Strukturelemente beispielsweise eingekapselt, und Sie können sie nicht als Mitglieder von bezeichnenDays
.Sie müssen , was Sie für mit der Suche C ++ 11 , die eine Einführung
enum class
:Beachten Sie, dass sich C ++ in einigen Punkten ein wenig von C unterscheidet. Zum einen erfordert C die Verwendung des
enum
Schlüsselworts, wenn eine Variable deklariert wird:quelle
Sie können einen Trick verwenden, um Bereiche nach Ihren Wünschen zu verwenden. Deklarieren Sie einfach die Aufzählung folgendermaßen:
quelle
Anstatt eine Reihe von if-Anweisungen zu verwenden, eignen sich Aufzählungen gut, um Anweisungen zu wechseln
Ich verwende einige Enum / Switch-Kombinationen in dem Level Builder, den ich für mein Spiel baue.
EDIT: Eine andere Sache, ich sehe, Sie wollen eine ähnliche Syntax;
Sie können dies in C ++ tun:
Hier ist ein sehr einfaches Beispiel:
EnumAppState.h
Somefile.cpp
quelle
Wenn Sie immer noch C ++ 03 verwenden und Aufzählungen verwenden möchten, sollten Sie Aufzählungen in einem Namespace verwenden. Z.B:
Sie können die Aufzählung außerhalb des Namespace wie folgt verwenden:
quelle
Sie suchen nach stark typisierten Aufzählungen , eine Funktion, die im C ++ 11- Standard verfügbar ist . Aufzählungen werden in Klassen mit Bereichswerten umgewandelt.
Anhand Ihres eigenen Codebeispiels ist dies:
Die Verwendung
::
als Accessoren für Aufzählungen schlägt fehl, wenn auf einen C ++ - Standard vor C ++ 11 abgezielt wird. Einige alte Compiler unterstützen dies jedoch nicht. Einige IDEs überschreiben diese Option einfach und legen einen alten C ++ - Standard fest.Wenn Sie GCC verwenden, aktivieren Sie C + 11 mit -std = c ++ 11 oder -std = gnu11 .
Sei glücklich!
quelle
enum class Days { ...
.Dies sollte in C ++ nicht funktionieren:
Tage ist kein Bereich oder Objekt, das Mitglieder enthält, auf die Sie mit dem Punktoperator zugreifen können. Diese Syntax ist nur ein C # -Imismus und in C ++ nicht zulässig.
Microsoft hat seit langem eine C ++ - Erweiterung beibehalten, mit der Sie mithilfe des Bereichsoperators auf die Bezeichner zugreifen können:
Dies ist jedoch vor C ++ 11 kein Standard. In C ++ 03 existieren die in einer Aufzählung deklarierten Bezeichner nur im selben Bereich wie der Aufzählungstyp selbst.
In C ++ 11 ist es zulässig, Enum-Bezeichner mit dem Enum-Namen zu qualifizieren, und es werden Enum-Klassen eingeführt, die einen neuen Bereich für die Bezeichner erstellen, anstatt sie in den umgebenden Bereich zu setzen.
quelle
Während C ++ (außer C ++ 11) Aufzählungen enthält, werden die darin enthaltenen Werte in den globalen Namespace "durchgesickert".
Wenn Sie nicht möchten, dass sie durchgesickert sind (und nicht den Aufzählungstyp verwenden MÜSSEN), beachten Sie Folgendes:
quelle
Leider sind Elemente der Aufzählung "global". Sie greifen auf sie zu, indem Sie dies tun
day = Saturday
. Das bedeutet, dass Sie nicht haben könnenenum A { a, b } ;
undenum B { b, a } ;
für sie in Konflikt stehen.quelle
enum class
in C ++ 11 verwenden. Vorher müssen Sie Dummy-Klassen erstellen.Aufzählungen in C ++ sind wie Ganzzahlen, die durch die Namen maskiert werden, die Sie ihnen geben, wenn Sie Ihre Aufzählungswerte deklarieren (dies ist keine Definition, sondern nur ein Hinweis darauf, wie es funktioniert).
Ihr Code enthält jedoch zwei Fehler:
enum
alle KleinbuchstabenDays.
vor Samstag.if (day == YourClass::Saturday){}
quelle
Ich denke, Ihr Hauptproblem ist die Verwendung von
.
anstelle von::
, wodurch der Namespace verwendet wird.Versuchen:
quelle
Days::
Bereich wie in Ihrem Beispiel zu verwenden, müssen Sie die Aufzählung mitenum class Days
C ++ 03 + Microsoft-Erweiterung oder C ++ 11 definieren und verwenden.-std=c++98
oder kompiliert wurde-std=c++03
. Clang ist ganz klar :warning: use of enumeration in a nested name specifier is a C++11 extension
.Wenn wir die strenge Typensicherheit und die Enumeration mit Gültigkeitsbereich wünschen, ist die Verwendung
enum class
in C ++ 11 gut.Wenn wir in C ++ 98 arbeiten mussten, können wir die Ratschläge von verwenden
InitializeSahib
,San
um die Enumeration mit Gültigkeitsbereich zu aktivieren.Wenn wir auch die strenge Typensicherheit wollen, kann der folgende Code so etwas implementieren
enum
.Der Code wurde gegenüber dem Beispiel für die Klasse Monat in Buch Effective C ++ 3: Punkt 18 geändert
quelle
Machen Sie zuerst 'E' in Aufzählung, 'e' als Kleinbuchstaben.
Zweitens geben Sie den Typnamen 'Days' in 'Days.Saturday' ein.
Drittens ... kaufen Sie sich ein gutes C ++ - Buch.
quelle