Wie kann man int in C ++ in enum umwandeln?

222

Wie wandle ich ein Int in eine Aufzählung in C ++ um?

Beispielsweise:

enum Test
{
    A, B
};

int a = 1;

Wie konvertiere ich ain Typ Test::A?

user1509260
quelle
1
link Beachten Sie, dass es keine Rolle spielt, ob das int mit einer der Konstanten des Aufzählungstyps übereinstimmt. Die Typkonvertierung ist immer illegal.
Iwaz
3
Ich glaube, wenn Sie in Test :: A umwandeln möchten, muss der Wert von int a0 sein, da Test :: A einen impliziten Wert von 0 und Test :: B einen impliziten Wert von 1 hat speziell zu Test :: A ist neben dem Punkt ...
JohnRDOrazio

Antworten:

243
int i = 1;
Test val = static_cast<Test>(i);
Andrew
quelle
21
auto val = static_cast <Test> (i); // C ++ 11
Mitch
3
@Mitch was bekomme ich autoin diesem Fall für die Verwendung ? Gibt es Leistungsverbesserungen?
Frederico Pantuzza
2
Keine Leistungsverbesserungen. Der Compiler leitet den Typ nur automatisch ab, wenn Sie mit "auto" angeben. Wenn Sie Ihren Aufzählungsnamen in Zukunft ändern möchten, ändern Sie Ihren Code weniger, da der Compiler automatisch den richtigen Typnamen ableitet.
Aydin Özcan
74
Test e = static_cast<Test>(1);
bames53
quelle
10
MSDN: Der Operator static_cast kann einen ganzzahligen Wert explizit in einen Aufzählungstyp konvertieren. Wenn der Wert des Integraltyps nicht in den Bereich der Aufzählungswerte fällt, ist der resultierende Aufzählungswert undefiniert.
Kirill
1
@KirillKobelev Wenn der Integralwert durch den zugrunde liegenden Typ der Aufzählung dargestellt werden kann, muss die resultierende Aufzählung diesen Wert haben. Andernfalls ist der erzeugte Aufzählungswert der Wert, der sich aus der Konvertierung des Ausdrucks in den zugrunde liegenden Aufzählungstyp ergibt. Wenn VC ++ etwas anderes macht, denke ich, dass es nicht konform ist.
Bames53
2
Was sollte ein konformer Compiler tun, wenn enum Werte {1,3,5} hat und Code versucht, <static_cast> vom Wert 2 auszuführen? Wie unterscheidet sich das vom C-Cast?
Kirill Kobelev
6
@KirillKobelev Ich verwende keinen static_cast, da er sich von einem C-Cast unterscheidet. Ich verwende static_cast, weil C ++ - Casts C-Casts stilistisch vorzuziehen sind.
Bames53
4
@KirillKobelev " wenn die Aufzählung Werte {1,3,5} hat " Nein. Der Aufzählungstyp kann nicht nur auf diese 3 möglichen Werte beschränkt werden: {1,3,5} sind die Aufzähler (benannte Aufzählungswerte), nicht die Aufzählung selbst . Wenn 1,3,5 mögliche Aufzählungswerte sind, ist dies auch 2.
neugieriger Kerl
25

Dein Code

enum Test
{
    A, B
}

int a = 1;

Lösung

Test castEnum = static_cast<Test>(a);
user1515687
quelle
45
Es ist eine gute Idee, die restriktivste Besetzung zu verwenden und C-artige Besetzungen insgesamt zu vermeiden, um dem Compiler die beste Chance zu geben, Fehler zu erkennen. static_castwäre hier eine bessere Besetzung.
Mike Seymour
4
@ Mike Seymour, das Problem ist, dass der statische Cast in diesem Fall keinen Unterschied zum C-Cast hat. Wie und welchen Fehler kann es erkennen ???
Kirill Kobelev
7
@KirillKobelev: Das Problem ist, dass eine Besetzung im C-Stil nicht explizit ist. Es kann gleich a sein static_cast, aber es kann genauso gut ein const_castoder noch schlimmer sein, ein reinterpret_castoder sogar eine Kombination davon. Selbst wenn Sie jetzt wissen, wie es sich verschlechtern wird, nehmen wir an, Sie wechseln später azu einem anderen Typ. Es könnte sich durchaus um die Art der Casting-Änderungen handeln, ohne dass Sie jemals eine Warnung erhalten. Das wollen Sie nicht.
KillianDS
4
@KillianDS " Angenommen, Sie ändern später einen in einen anderen Typ " Welcher Typ?
Neugieriger
2
Ja, entweder diese oder eine implizite Besetzung, falls verfügbar. Es ist viel klarer, was die Absicht der Besetzung ist.
KillianDS
8

Spinnen die abschließende Frage ab : „Wie konvertiere ich ein zu geben Test::A“ und nicht als starr über die Anforderung ist , eine haben , Guss drin, und die Beantwortung spät nur einige Jahre das niemand eine beliebte Frage scheint zu sein scheint sonst die Alternative erwähnt zu haben gemäß dem C ++ 11-Standard:

5.2.9 Statische Besetzung

... kann ein Ausdruck unter Verwendung eines Formulars eexplizit in einen Typ konvertiert werden, wenn die Deklaration für eine erfundene temporäre Variable (8.5) wohlgeformt ist . Der Effekt einer solchen expliziten Konvertierung entspricht der Durchführung der Deklaration und Initialisierung und der anschließenden Verwendung der temporären Variablen als Ergebnis der Konvertierung.Tstatic_caststatic_cast<T>(e)T t(e);t

Daher t(e)funktioniert auch die direkte Verwendung des Formulars , und Sie bevorzugen es möglicherweise aus Gründen der Übersichtlichkeit:

auto result = Test(a);
Tommy
quelle
Diese Lösung funktionierte, falls die Compileroption static_cast <> blockierte (semantische Prüfung). Nicht, dass es für mich Sinn macht, aber trotzdem ordentlich.
Herr Buisson
1

Test castEnum = static_cast<Test>(a-1);wird ein zu A werfen. Wenn Sie Unterkonstruktion 1 nicht wollen, können Sie neu definieren enum:

enum Test
{
    A:1, B
};

In diesem Fall `Test castEnum = static_cast (a); ' könnte verwendet werden, um ein zu A zu werfen.

kosolapyj
quelle