Frage

Sind C ++ Aufzählungen oder ohne Vorzeichen? Und durch die Erweiterung ist es sicher eine Eingabe zu validieren, indem die Überprüfung, dass es <= Ihr max-Wert und auslassen> = Ihr Minimalwert (vorausgesetzt, Sie begann bei 0 und um 1 erhöht)?

War es hilfreich?

Lösung

Sie sollten sich nicht auf eine bestimmte Darstellung verlassen. Lesen Sie die folgenden Link . Auch sagt der Standard, dass es die Implementierung definiert, die integrale Typ wie der zugrunde liegende Typ für eine Enumeration verwendet wird, mit der Ausnahme, dass es nicht als int größer sein wird, wenn nicht ein Wert nicht in int oder unsigned int passen kann.

Kurz gesagt:. Sie können nicht auf einer Enumeration verlassen entweder mit oder ohne Vorzeichen

Andere Tipps

Lassen Sie uns an die Quelle gehen. Hier ist, was der C ++ 03-Standard (ISO / IEC 14882: 2003) Dokument sagt in 7,2-5 (Enumeration Erklärungen):

  

Der zugrunde liegende Typ einer Aufzählung   ist ein integraler Typ, der darstellen kann   alle Werte definiert in Enumerator   die Aufzählung. Es ist   Implementierung definiert, die integrale   Typ wird als Grundtyp verwendet   für eine Aufzählung der Ausnahme, dass die   zugrunde liegende Typ darf nicht größer sein   als int, es sei denn der Wert eines   enumerator kann nicht in einem int passen oder   unsigned int.

Kurz gesagt, Ihr Compiler wird (natürlich, wenn Sie für einige Ihrer ennumeration Werte negative Zahlen haben, werden sie zu unterzeichnen) zu wählen.

Sie sollten nicht von ihnen abhängig sind mit oder ohne Vorzeichen ist. Wenn Sie sie explizit mit oder ohne Vorzeichen machen möchten, können Sie die folgenden Befehle verwenden:

enum X : signed int { ... };    // signed enum
enum Y : unsigned int { ... };  // unsigned enum

Sie sollten nicht auf sie verlassen, entweder mit oder ohne Vorzeichen ist. Gemäß dem Standard ist es, die Implementierung definierte integraler Typ als Grundtyp für ein ENUM verwendet wird. In den meisten Implementierungen ist es allerdings eine ganze Zahl mit Vorzeichen.

In C ++ 0x stark Aufzählungen getippt hinzugefügt werden die ermöglicht es Ihnen, den Typ eines eNUM wie angeben:

enum X : signed int { ... };    // signed enum
enum Y : unsigned int { ... };  // unsigned enum

Schon jetzt aber können einige einfache Validierung mithilfe der Enum als Variable oder Parametertyp wie dies erreicht werden:

enum Fruit { Apple, Banana };

enum Fruit fruitVariable = Banana;  // Okay, Banana is a member of the Fruit enum
fruitVariable = 1;  // Error, 1 is not a member of enum Fruit
                    // even though it has the same value as banana.

Der Compiler kann entscheiden, ob oder nicht Aufzählungen sind mit oder ohne Vorzeichen.

Eine andere Methode Aufzählungen der Validierung ist der ENUM selbst als Variablentyp zu verwenden. Zum Beispiel:

enum Fruit
{
    Apple = 0,
    Banana,
    Pineapple,
    Orange,
    Kumquat
};

enum Fruit fruitVariable = Banana;  // Okay, Banana is a member of the Fruit enum
fruitVariable = 1;  // Error, 1 is not a member of enum Fruit even though it has the same value as banana.

Auch einige alte Antworten 44 upvotes bekam, neige ich dazu, mit allen von ihnen zu widersprechen. Kurz gesagt, ich glaube nicht, dass wir über die underlying type der Enumeration kümmern sollten.

Als erstes, C ++ 03 Enum-Typ ist eine eindeutige Art der eigenen kein Konzept Vorzeichen. Da von C ++ 03-Standard dcl.enum

7.2 Enumeration declarations 
5 Each enumeration defines a type that is different from all other types....

Wenn wir also über das Zeichen eines Aufzählungstyp sprechen, sagen, wenn 2 Enum Operanden Vergleichen des < Operator, sprechen wir eigentlich über implizit den Aufzählungstyp zu einem gewissen ganzzahligen Typ konvertieren. Es ist das Zeichen dieses integralen Typ, zählt. Und wenn Enum zu integralem Typ Konvertierung diese Aussage gilt:

9 The value of an enumerator or an object of an enumeration type is converted to an integer by integral promotion (4.5).

Und offenbar der zugrunde liegende Typ der Enumeration bekommt nichts mit der Integral Promotion zu tun. Da der Standard wie dieses Integral Promotion definiert:

4.5 Integral promotions conv.prom
.. An rvalue of an enumeration type (7.2) can be converted to an rvalue of the first of the following types that can represent all the values of the enumeration
(i.e. the values in the range bmin to bmax as described in 7.2: int, unsigned int, long, or unsigned long.

Also, ob ein Aufzählungstyp signed int oder unsigned int wird hängt davon ab, ob signed int alle Werte der definierten Aufzählungen enthalten, nicht der zugrunde liegende Typ der Enumeration.

Sehen Sie meine damit verbundene Frage Zeichen von C ++ Enum-Typ falsch, nachdem an Integral Converting Geben Sie

In der Zukunft mit C ++ 0x, stark Aufzählungen getippt verfügbar sein und mehrere Vorteile (wie Typ-Sicherheit, explizit zugrunde liegenden Typen, oder explizite Scoping) haben. Damit Sie besser gesichert des Zeichens des Typs sein könnten.

Zusätzlich zu dem, was andere gesagt haben, bereits über / ohne Vorzeichen, hier ist, was der Standard sagt über die Reichweite eines Aufzählungstyp:

7.2 (6): „Für eine Aufzählung, wobei e (min) ist die kleinste enumerator und e (max) ist die größte, die Werte der Aufzählung sind die Werte des zugrunde liegenden Typs im Bereich b (min) bis b (max), wobei b (min) und b (max) sind jeweils die kleinsten und größten Werte der kleinsten Bitfeld, das e speichern kann (min) und E (max). Es ist möglich, eine Aufzählung zu definieren, die aufweist Werte nicht durch eines ihrer Aufzählungen definiert. "

So zum Beispiel:

enum { A = 1, B = 4};

definiert einen Aufzählungstyp, wobei e (min) 1 ist und e (max) 4. Wenn der zugrunde liegende Typ int signiert ist, dann ist die kleinste erforderliche bitfield hat 4 Bits, und wenn Ints in Ihrer Implementierung Ergänzung Zweierkomplement sind dann die gültige Bereich der Enumeration ist -8 bis 7. wenn der zugrunde liegende Typ unsigned ist, dann hat es 3 Bits und der Bereich 0 bis 7 Compiler Dokumentation Überprüfen Sie, ob Sie (zB Pflege, wenn Sie andere ganzzahlige Werte werfen wollen, als Enumeratoren auf den Aufzählungstyp, dann müssen Sie wissen, ob der Wert im Bereich der Aufzählung ist oder nicht - wenn nicht der resultierende enum-Wert ist nicht spezifiziert)

.

Ob diese Werte gültige Eingabe an Ihre Funktion aus einem anderen Problem kann sein, ob sie gültige Werte des Aufzählungstyp sind. Ihre Prüfcodes sind wahrscheinlich besorgt über die ehemaligen eher als letztere, und so in diesem Beispiel zumindest sollte die Überprüfung> = A und <= B.

Überprüfen Sie es mit std::is_signed<std::underlying_type + scoped Aufzählungen Standard int

https://en.cppreference.com/w/cpp/language/enum bedeutet:

main.cpp

#include <cassert>
#include <iostream>
#include <type_traits>

enum Unscoped {};
enum class ScopedDefault {};
enum class ScopedExplicit : long {};

int main() {
    // Implementation defined, let's find out.
    std::cout << std::is_signed<std::underlying_type<Unscoped>>() << std::endl;

    // Guaranteed. Scoped defaults to int.
    assert((std::is_same<std::underlying_type<ScopedDefault>::type, int>()));

    // Guaranteed. We set it ourselves.
    assert((std::is_same<std::underlying_type<ScopedExplicit>::type, long>()));
}

GitHub Upstream .

Kompilieren und Ausführen:

g++ -std=c++17 -Wall -Wextra -pedantic-errors -o main main.cpp
./main

Ausgabe:

0

Getestet auf Ubuntu 16.04, GCC 6.4.0.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top