2008-09-16 15 views
17

Gibt es eine Möglichkeit, eine 64-Bit-Enumeration in C++ zu haben? Beim Refactoring von Code bin ich auf eine Menge von #defines gestoßen, die besser als Enum wären, aber mit mehr als 32 Bit wird der Compiler fehlerhaft.64-Bit-Enumeration in C++?

Aus irgendeinem Grund dachte ich folgendes funktionieren könnte:

enum MY_ENUM : unsigned __int64 
{ 
    LARGE_VALUE = 0x1000000000000000, 
}; 
+0

Gibt es einen Grund 'unsigned __int64' über' uint64_t' zu bevorzugen? Ich denke, "uint64_t" ist für fast jede relevante Plattform definiert, aber "unsigned __int64" klingt wie eine Plattformdefinition (Hardware, Compiler oder sogar Bibliothek). – Johan

Antwort

14

Ich denke nicht, dass das mit C++ 98 möglich ist. Die zugrunde liegende Darstellung von Enums ist dem Compiler überlassen. Verwendung In diesem Fall sind Sie besser dran:

const __int64 LARGE_VALUE = 0x1000000000000000L; 

Ab C 11 ++ ist es möglich, Enum-Klassen zu verwenden, um den Basistyp der Enumeration angeben:

enum class MY_ENUM : unsigned __int64 { 
    LARGE_VALUE = 0x1000000000000000ULL 
}; 

Zusätzlich Enum Klassen führen einen neuen Namensumfang ein. Anstatt sich auf LARGE_VALUE zu beziehen, würden Sie sich auf MY_ENUM::LARGE_VALUE beziehen.

+0

Dies ist, was ich am Ende verwendet habe, aber ich war neugierig, ob 64-Bit-Enums möglich sind, auch mit einer Compiler-spezifischen Erweiterung. – Rob

0

Ein Enum in C++ jeder integralen Typ sein kann. Sie können zum Beispiel eine Reihe von Zeichen haben. IE:

enum MY_ENUM 
{ 
    CHAR_VALUE = 'c', 
}; 

Ich würde annehmen dies schließt __int64. nur

enum MY_ENUM 
{ 
    LARGE_VALUE = 0x1000000000000000, 
}; 
versucht

Nach meinem Kommentator, sixlettervariables, in C der Basistyp wird ein int immer sein, während in C++ der Basistyp ist, was groß genug ist, den größten Wert enthalten passen. Also sollten beide Enums oben funktionieren.

+1

@Doug T .: Während ANSI C diktiert, dass Aufzählungen die Größe des Datentyps 'int' sind, schreibt ISO C++ vor, dass Aufzählungen mindestens so groß sind, wie für die Darstellung aller Werte erforderlich ist. – user7116

1

Da Sie in C++ arbeiten, könnte eine weitere Alternative

const __int64 LARVE_VALUE = ... 

Dies kann in einer H-Datei angegeben werden.

+0

Ich betrog 9 Zeichen beim ersten Versuch. – Behrooz

2

Wenn der Compiler 64-Bit-Enums nicht durch Kompilierungs-Flags oder andere Mittel unterstützt, denke ich, dass es keine Lösung für diesen gibt.

Man könnte so etwas wie in Ihrem Beispiel so etwas wie erstellen:

namespace MyNamespace { 
const uint64 LARGE_VALUE = 0x1000000000000000; 
}; 

und es ist wie ein Enum mit mit

MyNamespace::LARGE_VALUE 

oder

using MyNamespace; 
.... 
val = LARGE_VALUE; 
+1

Und lose Art Sicherheit, obwohl. –

+0

Leider ja – INS

+2

Die Geschwindigkeit unserer Konversation erinnert mich an Fernschach: D –

1

Ihre snipplet des Codes nicht C++ Standard:

Enum MY_ENUM: unsigned __int64

macht keinen Sinn.

Verwendung const __int64 stattdessen als Torlack

diesen
+0

er prolly es in einer anderen geschweiften Klammer Sprache gesehen hat (z. B. C# unterstützt) oder im kommenden C++ - Standard, wo dies erlaubt ist. –

17

C++ 11 unterstützt schon sagt, mit folgenden Syntax:

enum class Enum2 : __int64 {Val1, Val2, val3}; 
+0

Ich war in der Nähe dann. Ich muss irgendwo über die ': type'-Syntax lesen. – Rob

+2

Beachten Sie, dass 'class' immer noch optional ist. Wenn Sie möchten, alte Stil enum, aber mit einem benutzerdefinierten Typ, können Sie auch 'enum moo: long long {...}' –

4

Die Antworten auf beziehen __int64 das Problem zu verpassen. Das Enum ist gültig in allen C++ - Compilern, die einen echten 64-Bit-Integraltyp aufweisen, d. H. Einen C++ 11-Compiler oder C++ 03-Compiler mit entsprechenden Erweiterungen. Erweiterungen zu C++ 03 wie __int64 arbeiten unterschiedlich über Compiler, einschließlich seiner Eignung als Basistyp für Enums.

0

In MSVC++ Sie können dies tun:

Enum MYLONGLONGENUM: __ int64 {BIG_KEY = 0x3034303232303330, ...};

+2

besser int64-max als eine magische wilde Vermutung verwenden. –

5

Der aktuelle Entwurf der so C++0x genannt, es n3092 sagt in 7.2 Enumeration Erklärungen ist, Ziffer 6:

Es ist die Implementierung definiert, die integraler Typ als zugrunde liegende Typ der Ausnahme, dass verwendet wird, Der zugrunde liegende Typ darf nicht größer sein als als int, es sei denn, der Wert eines Enumerators kann nicht in einen int oder unsigned int passen.

selben Absatz sagt auch:

Wenn kein integraler Typ alle die Aufzählungswerte darstellen, die Aufzählung ist schlecht ausgebildet.

Meine Interpretation des Teils es sei denn, der Wert eines Aufzählungs nicht in einem int oder unsigned int passen kann, ist, dass es vollkommen gültig und sicher ist enumerator zu initialisieren mit 64-Bit-Integer-Wert, solange es ist 64- Bit-Integer-Typ, der in einer bestimmten C++ - Implementierung bereitgestellt wird.

Zum Beispiel:

enum MyEnum 
{ 
    Undefined = 0xffffffffffffffffULL 
}; 
+3

Wenn du deine f's nicht zählen willst, kannst du 'Undefined = ~ 0x0ULL' machen –

1

Aufzählungstyp wird in der Regel durch den Datentyp der ersten ENUM-Initialisierer bestimmt. Wenn der Wert den Bereich für diesen Integral-Datentyp überschreiten sollte, stellt der C++ - Compiler sicher, dass er mit einem größeren Integraldatentyp passt. Wenn der Compiler feststellt, dass er nicht zu dem Integraltyp gehört, löst der Compiler einen Fehler aus. Ref: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1905.pdf
Edit: Dies ist jedoch rein hängt von Maschinenarchitektur