Diese Frage kam mir in den Sinn, als ich so etwas hatte
enum Folders {FA, FB, FC};
und wollte ein Array von Containern für jeden Ordner erstellen:
ContainerClass*m_containers[3];
....
m_containers[FA] = ...; // etc.
(Verwenden von Karten ist es viel eleganter zu verwenden: std::map<Folders, ContainerClass*> m_containers;
)
Um jedoch auf meine ursprüngliche Frage zurückzukommen: Was gibt es eine Möglichkeit, um herauszufinden, wie viele Elemente sich in Ordnern befinden, wenn ich die Arraygröße nicht fest codieren möchte? (Ohne sich darauf zu verlassen, dass z. B. FC
das letzte Element in der Liste ist, das so etwas zulässt, ContainerClass*m_containers[FC+1]
wenn ich mich nicht irre.)
c++
count
enumeration
fuenfundachtzig
quelle
quelle
int(FA) | int(FB) | int (FC)
ist dies auch ein zulässiger Wert für eineFolders
Variable. Wenn Sie die Größem_containers
so festlegen , dass eineFolders
Variable ein gültiger Index ist,[FC+1]
wäre sie nicht groß genug.Antworten:
Es gibt keinen wirklich guten Weg, dies zu tun. Normalerweise sehen Sie einen zusätzlichen Gegenstand in der Aufzählung, dh
Dann können Sie Folgendes tun:
Immer noch nicht sehr schön.
Aber natürlich stellen Sie fest, dass nur die Anzahl der Elemente in einer Aufzählung nicht sicher ist, z
Die Anzahl der Elemente wäre 4, aber die ganzzahligen Werte der Aufzählungswerte würden weit außerhalb des Array-Indexbereichs liegen. Die Verwendung von Enum-Werten für die Array-Indizierung ist nicht sicher. Sie sollten andere Optionen in Betracht ziehen.
Bearbeiten: Wie gewünscht, wurde der spezielle Eintrag stärker hervorgehoben.
quelle
Für C ++ stehen verschiedene typsichere Aufzählungstechniken zur Verfügung, und einige davon (wie die vorgeschlagene, aber nie übermittelte Boost.Enum ) unterstützen das Abrufen der Größe einer Aufzählung.
Der einfachste Ansatz, der sowohl in C als auch in C ++ funktioniert, besteht darin, eine Konvention zum Deklarieren eines ... MAX-Werts für jeden Ihrer Aufzählungstypen anzuwenden:
Bearbeiten : In Bezug auf
{ FA, FB, FC, Folders_MAX = FC}
versus{FA, FB, FC, Folders_MAX]
: Ich bevorzuge es aus einigen Gründen, den Wert ... MAX auf den letzten zulässigen Wert der Aufzählung zu setzen:Folders_MAX
den maximal möglichen Aufzählungswert ergibt).Folders_MAX = FC
von anderen Einträgen etwas mehr abheben (was es etwas schwieriger macht, versehentlich Aufzählungswerte hinzuzufügen, ohne den Maximalwert zu aktualisieren, ein Problem, auf das Martin York verwiesen hat).quelle
enum Folders { FA, FB, FC, Folders_MAX }; ContainerClass *m_containers[Folders_MAX];
?struct SomeEnum { enum type {FA, FB, FC, NB__};};
Wie wäre es mit Merkmalen auf STL-Weise? Zum Beispiel:
Schreib 'ein
Spezialisierung (möglicherweise constexpr, wenn Sie c ++ 11 verwenden). Geben Sie dann in Ihrem Testcode statische Zusicherungen an, um die Einschränkungen beizubehalten, die std :: numeric_limits :: max () = last_item sind.
quelle
std::numeric_limits<enum Foo>::max()
Gibt immer Null zurück ... (siehe die Frage für die verknüpfte Antwort) Getestet auf normalen Aufzählungen (enum Foo { ... }
), typgesteuerten Aufzählungen (enum class Foo : uint8_t { ... }
) mit gcc 5.2.0 @ Linux und MinGW 4.9.3 @ Windows.std::numeric_limits<std::underlying_type<Foo>::type>::max()
gibt es den Maximalwert des zugrunde liegenden Typs zurück, dh 0xFFFFFFFF für 32-Bit-Ganzzahlen, was in diesem Zusammenhang nicht nützlich ist.)namespace gx { enum struct DnaNucleobase : char { A, C, G, T }; }
Dann:namespace std { template<> struct numeric_limits<enum ::gx::DnaNucleobase> { typedef enum ::gx::DnaNucleobase value_type; static constexpr value_type max() { return value_type::T; } (...)
Undstd::cout << std::numeric_limits<::gx::DnaNucleobase>::max() << std::endl;
druckt das erwartete Ergebnis. Getestet mit den Geschmacksrichtungen gcc 5.2.1 und 4.8 / 4.9.numeric_limits<T>::max()
. Das einzige, was diese Funktion vernünftigerweise zurückgeben könnte, ist der höchste aufgezählte Wert. Es würde zurückkehren2
, aber das OP (in diesem speziellen Fall) würde es brauchen, um zurückzukehren3
. Sobald Sie nicht standardmäßige Werte für enum (FB = 2057
) haben, sind alle Wetten deaktiviert und können nicht einmal+ 1
den Fehler "by-by-one" umgehen. Wenn es einennumeric_limits<T>::number_of_elements_of_the_set()
(oder einen kürzeren) Namen gäbe , könnte dieser ohne Mehrdeutigkeit verwendet werden.Fügen Sie am Ende Ihrer Aufzählung einen Eintrag mit dem Namen Folders_MAX oder ähnliches hinzu und verwenden Sie diesen Wert beim Initialisieren Ihrer Arrays.
quelle
Ich verwende gerne Aufzählungen als Argumente für meine Funktionen. Es ist ein einfaches Mittel, eine feste Liste von "Optionen" bereitzustellen. Das Problem mit der am besten bewerteten Antwort hier ist, dass ein Client damit eine "ungültige Option" angeben kann. Als Nebeneffekt empfehle ich, im Wesentlichen dasselbe zu tun, aber ein konstantes int außerhalb der Aufzählung zu verwenden, um die Anzahl von ihnen zu definieren.
Es ist nicht angenehm, aber es ist eine saubere Lösung, wenn Sie die Aufzählung nicht ändern, ohne die Konstante zu aktualisieren.
quelle
Ich sehe wirklich keine Möglichkeit, die Anzahl der Werte in einer Aufzählung in C ++ wirklich zu erreichen. Jede der oben genannten Lösungen funktioniert, solange Sie den Wert Ihrer Aufzählungen nicht definieren, wenn Sie einen Wert definieren, der möglicherweise auf Situationen stößt, in denen Sie entweder zu große oder zu kleine Arrays erstellen
In diesem Beispiel würde das Ergebnis ein Array von 3 Elementen erstellen, wenn Sie ein Array von 5 Elementen benötigen
In diesem Beispiel würde das Ergebnis ein Array von 301 Elementen erstellen, wenn Sie ein Array von 5 Elementen benötigen
Der beste Weg, um dieses Problem im allgemeinen Fall zu lösen, wäre, Ihre Aufzählungen zu durchlaufen, aber das ist meines Wissens noch nicht im Standard
quelle