Frage (Wie) kann ich die Gegenstände in einer Aufzählung zählen?


Diese Frage kam mir in den Sinn, als ich so etwas hatte

enum Folders {FA, FB, FC};

und wollte für jeden Ordner ein Array von Containern erstellen:

ContainerClass*m_containers[3];
....
m_containers[FA] = ...; // etc.

(Mit Karten ist es viel eleganter zu verwenden: std::map<Folders, ContainerClass*> m_containers;)

Aber um zu meiner ursprünglichen Frage zurückzukommen: Was ist, wenn ich die Array-Größe nicht fest codieren möchte, gibt es eine Möglichkeit herauszufinden, wie viele Elemente sich in Ordnern befinden? (Ohne sich auf z.B. FC ist der letzte Punkt in der Liste, der so etwas erlauben würde ContainerClass*m_containers[FC+1] wenn ich mich nicht irre.)


76
2018-01-20 15:37


Ursprung


Antworten:


Es gibt nicht wirklich einen guten Weg, dies zu tun, normalerweise sehen Sie einen zusätzlichen Gegenstand in der Enum, d.

enum foobar {foo, bar, baz, quz, FOOBAR_NR_ITEMS};

Dann kannst du Folgendes tun:

int fuz[FOOBAR_NR_ITEMS];

Immer noch nicht sehr nett.

Aber natürlich wissen Sie, dass nur die Anzahl der Elemente in einem Enum nicht sicher ist, z.

enum foobar {foo, bar = 5, baz, quz = 20};

Die Anzahl der Elemente wäre 4, aber die Ganzzahlwerte der Aufzählungswerte würden weit außerhalb des Array-Indexbereichs liegen. Die Verwendung von Aufzählungswerten für die Array-Indexierung ist nicht sicher. Sie sollten daher andere Optionen in Betracht ziehen.

edit: wie gewünscht, machte der spezielle Eintrag mehr aus.


98
2018-01-20 15:42



Für C ++ gibt es verschiedene typsichere Enum-Techniken zur Verfügung, und einige von ihnen (wie die vorgeschlagene, aber nie eingereicht Boost.Enum) beinhalten Unterstützung für die Größe eines Enums.

Der einfachste Ansatz, der sowohl in C als auch in C ++ funktioniert, besteht darin, eine Konvention für die Deklaration eines ... MAX-Wertes für jeden Ihrer Enum-Typen zu übernehmen:

enum Folders { FA, FB, FC, Folders_MAX = FC };
ContainerClass *m_containers[Folders_MAX + 1];
....
m_containers[FA] = ...; // etc.

Bearbeiten: Bezüglich { FA, FB, FC, Folders_MAX = FC} gegen {FA, FB, FC, Folders_MAX]: Ich bevorzuge es, den MAX-Wert auf den letzten gültigen Wert der Enumeration aus ein paar Gründen zu setzen:

  1. Der Name der Konstanten ist technisch genauer (seit Folders_MAX gibt den maximal möglichen Enum-Wert an).
  2. Persönlich fühle ich mich wie Folders_MAX = FC hebt sich von anderen Einträgen etwas mehr ab (was es ein bisschen schwieriger macht, enum-Werte hinzuzufügen, ohne den Maximalwert zu aktualisieren, ein Problem, auf das Martin York Bezug genommen hat).
  3. GCC enthält hilfreiche Warnungen wie "Aufzählungswert, der nicht im Switch enthalten ist" für Code wie den folgenden. Das Löschen von Folders_MAX == FC + 1 bricht diese Warnungen, da Sie mit einer Reihe von MAX-Enumerationswerten enden, die in Switch nie enthalten sein sollten.
wechseln (Ordner)
{
  Fall FA: ...;
  Fall FB: ...;
  // Hoppla, vergessen FC!
}

27
2018-01-20 15:48



Wie wäre es mit Merkmalen, in einer STL-Mode? Zum Beispiel:

enum Foo
{
    Bar,
    Baz
};

Schreib 'ein

std::numeric_limits<enum Foo>::max()

Spezialisierung (möglicherweise constexpr, wenn Sie c ++ 11 verwenden). Stellen Sie dann in Ihrem Testcode statische Behauptungen bereit, um die Einschränkungen zu erhalten, die std :: numeric_limits :: max () = last_item.


5
2017-12-23 13:23



Fügen Sie am Ende Ihrer Enumeration einen Eintrag namens Folders_MAX oder etwas Ähnliches hinzu und verwenden Sie diesen Wert beim Initialisieren Ihrer Arrays.

ContainerClass* m_containers[Folders_MAX];

3
2018-01-20 15:42



Ich sehe wirklich keine Möglichkeit, die Anzahl der Werte in einer Aufzählung in C ++ zu erreichen. Jede der zuvor erwähnten Lösungen funktioniert so lange, wie Sie den Wert Ihrer Enumerationen nicht definieren, wenn Sie Ihren Wert definieren, der in Situationen auftreten könnte, in denen Sie Arrays entweder zu groß oder zu klein erstellen

enum example{ test1 = -2, test2 = -1, test3 = 0, test4 = 1, test5 = 2 }

In diesen Beispielen würde das Ergebnis ein Array von 3 Elementen erstellen, wenn Sie ein Array mit 5 Elementen benötigen

enum example2{ test1 , test2 , test3 , test4 , test5 = 301 }

In diesen Beispielen würde das Ergebnis ein Array von 301 Elementen erstellen, wenn Sie ein Array mit 5 Elementen benötigen

Der beste Weg, um dieses Problem im allgemeinen Fall zu lösen, wäre, durch Ihre Aufzählungen zu iterieren, aber das ist, soweit ich weiß, noch nicht im Standard


1
2018-01-12 23:59



Ich verwende Enums als Argumente für meine Funktionen. Es ist ein einfaches Mittel, um eine feste Liste von "Optionen" zur Verfügung zu stellen. Das Problem mit der oben gewählten Antwort ist, dass ein Client eine "ungültige Option" angeben kann. Als Spin-Off empfehle ich, im Wesentlichen das Gleiche zu tun, aber benutze eine Konstante int außerhalb der Enum, um die Anzahl von ihnen zu definieren.

enum foobar { foo, bar, baz, quz };
const int FOOBAR_NR_ITEMS=4;

Es ist nicht angenehm, aber es ist eine saubere Lösung, wenn Sie die Enum nicht ändern, ohne die Konstante zu aktualisieren.


1
2017-11-13 22:14