Mir ist gerade aufgefallen, dass man die Standard-Mathematik-Operatoren nicht auf eine enum
wie zum Beispiel ++
o +=
.
Wie kann man also am besten durch alle Werte in einer C++-Datei iterieren? enum
?
Mir ist gerade aufgefallen, dass man die Standard-Mathematik-Operatoren nicht auf eine enum
wie zum Beispiel ++
o +=
.
Wie kann man also am besten durch alle Werte in einer C++-Datei iterieren? enum
?
Vorteile: Enums können beliebige Werte in beliebiger Reihenfolge enthalten, und es ist immer noch einfach, über sie zu iterieren. Namen und Werte werden einmal definiert, im ersten #define.
Nachteile: Wenn Sie es bei der Arbeit verwenden, brauchen Sie einen ganzen Absatz, um es Ihren Kollegen zu erklären. Und es ist ärgerlich, Speicher deklarieren zu müssen, um Ihrer Schleife etwas zu geben, über das sie iterieren kann, aber ich kenne keinen Workaround, der Sie nicht auf Enums mit benachbarten Werten beschränkt (und wenn das Enum immer benachbarte Werte haben wird, bringt Ihnen das Enum vielleicht sowieso nicht viel).
//create a, b, c, d as 0, 5, 6, 7
#define LIST x(a) x(b,=5) x(c) x(d)
#define x(n, ...) n __VA_ARGS__,
enum MyEnum {LIST}; //define the enum
#undef x //needed
#define x(n,...) n ,
MyEnum myWalkableEnum[] {LIST}; //define an iterable list of enum values
#undef x //neatness
int main()
{
std::cout << d;
for (auto z : myWalkableEnum)
std::cout << z;
}
//outputs 70567
Der Trick, eine Liste mit einem undefinierten Makro-Wrapper zu deklarieren und dann den Wrapper in verschiedenen Situationen anders zu definieren, hat viele andere Anwendungen als diese.
Es gibt bereits eine Diskussion über std::initializer_list (C++11) in den Kommentaren. Ich erwähne ein Beispiel, um über die Aufzählung zu iterieren.
oder std::initializer_list und eine einfachere Syntax:
enum E {
E1 = 4,
E2 = 8,
// ..
En
};
constexpr std::initializer_list<E> all_E = {E1, E2, /*..*/ En};
und dann
for (auto e : all_E) {
// Do job with e
}
Referenz Link
Wenn Sie Ihre Aufzählung nicht mit einem abschließenden COUNT-Element verschmutzen möchten (denn wenn Sie die Aufzählung auch in einem Schalter verwenden, wird der Compiler Sie vielleicht vor einem fehlenden Fall COUNT: warnen), können Sie dies tun:
enum Colour {Red, Green, Blue};
const Colour LastColour = Blue;
Colour co(0);
while (true) {
// do stuff with co
// ...
if (co == LastColour) break;
co = Colour(co+1);
}
Für MS-Compiler:
#define inc_enum(i) ((decltype(i)) ((int)i + 1))
enum enumtype { one, two, three, count};
for(enumtype i = one; i < count; i = inc_enum(i))
{
dostuff(i);
}
Hinweis: Dies ist viel weniger Code als die einfache Antwort des benutzerdefinierten Iterators mit Vorlage.
Sie können dies mit GCC zum Laufen bringen, indem Sie typeof
anstelle von decltype
aber ich habe den Compiler im Moment nicht zur Hand, um sicherzustellen, dass er kompiliert.
In Bjarne Stroustrups Buch über die Programmiersprache C++ können Sie lesen, dass er vorschlägt, die operator++
für Ihr spezielles enum
. enum
sind benutzerdefinierte Typen, und für diese speziellen Situationen gibt es in der Sprache Überladungsoperatoren.
Sie können die folgenden Codes eingeben:
#include <iostream>
enum class Colors{red, green, blue};
Colors& operator++(Colors &c, int)
{
switch(c)
{
case Colors::red:
return c=Colors::green;
case Colors::green:
return c=Colors::blue;
case Colors::blue:
return c=Colors::red; // managing overflow
default:
throw std::exception(); // or do anything else to manage the error...
}
}
int main()
{
Colors c = Colors::red;
// casting in int just for convenience of output.
std::cout << (int)c++ << std::endl;
std::cout << (int)c++ << std::endl;
std::cout << (int)c++ << std::endl;
std::cout << (int)c++ << std::endl;
std::cout << (int)c++ << std::endl;
return 0;
}
Test-Code: http://cpp.sh/357gb
Beachten Sie, dass ich die enum class
. Der Code funktioniert gut mit enum
auch. Aber ich bevorzuge enum class
da sie stark typisiert sind und verhindern können, dass wir bei der Kompilierung Fehler machen.
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.