enum zu string
-
Janjan schrieb:
Eine Assertion wäre imho im Default-Zweig deutlich sinnvoller.
default: assert(false);
Aber nicht in der Release.
-
.... schrieb:
Janjan schrieb:
Eine Assertion wäre imho im Default-Zweig deutlich sinnvoller.
default: assert(false);
Aber nicht in der Release.
Im Release würde die Assertion nichts machen, und sowieso sollte dieser Code-Abschnitt niemals im Release erreichbar sein.
-
Janjan schrieb:
.... schrieb:
Janjan schrieb:
Eine Assertion wäre imho im Default-Zweig deutlich sinnvoller.
default: assert(false);
Aber nicht in der Release.
Im Release würde die Assertion nichts machen, und sowieso sollte dieser Code-Abschnitt niemals im Release erreichbar sein.
Hm, ich setze Debugger-Ausgaben oder Asserts ein, je nachdem wie schlimm der Fehler ist. Wenn anschließende Abstürze drohen, dann auf jeden Fall Assert. Kann der Fehler noch ein wenig stehenbleichen, dann Debugger-Ausgabe.
... schrieb:
Ich empfinde diese Variante als wesentlich sinniger:
enum T { A = 0, B, C }; char names[] = { 'A', 'B', 'C' };
Hm, sieht elegant aus, aber die Zuordnung kann leicht mal verloren gehen. Wie wäre es mit folgendem Code.
enum T { A = 0, B, C, last_enum }; char* names[last_enum]; names[A] = "Adam"; names[B] = "Eva"; names[C] = "Schlange"; };
Die Zuordnung bleibt auf jeden Fall erhalten, es kann nichts überlaufen und die Ausgabe ist etwas aussagekräftiger.
tschüß
Troll.Soft
-
Troll.Soft schrieb:
Hm, sieht elegant aus, aber die Zuordnung kann leicht mal verloren gehen. Wie wäre es mit folgendem Code.
enum T { A = 0, B, C, last_enum }; char* names[last_enum]; names[A] = "Adam"; names[B] = "Eva"; names[C] = "Schlange"; };
Die Zuordnung bleibt auf jeden Fall erhalten, es kann nichts überlaufen und die Ausgabe ist etwas aussagekräftiger.
Jopp, da hatte ich auch drüber nachgedacht - aber wie gesagt, da würde man überall code duplizieren...^^
da bräuchte man auch dasA = 0
nicht mehr...bb
-
unskilled schrieb:
da bräuchte man auch das
A = 0
nicht mehr...oops, ist auch nur aus Versehen stehengeblieben.
-
... schrieb:
Ich empfinde diese Variante als wesentlich sinniger:
enum T { A = 0, B, C }; char names[] = { 'A', 'B', 'C' };
Es gibt Situationen, in denen enums nicht lückenlos nummeriert sind und in denen funktionieren solche Varianten nicht.
Wir haben tw. "innere Strukturierungen" in größeren enum-Definitionen (ist nicht schön, aber bisweilen das kleinste Übel). Da ziehen wir dann doch die "switch-Variante" vor - da ist die Verknüpfung einfach direkter.Gruß,
Simon2.
-
Die switch-Variante geht aber halt auch nicht immer...
enum x { A, B, C = A };
Ich weiß zwar nicht mal mehr, wann das bei mir das letzte mal vorkam, aber naja... ^^
Aber stimmt schon, da ist die Troll.Soft-Variante immernoch die tollste...
bb
-
unskilled schrieb:
...
enum x { A, B, C = A };
...
Geht das?
Hätte gedacht, dass da ein Compiler Ärger macht... (und der Standard auch).Gruß,
Simon2.
-
Hat was von deprecated Enum-Einträgen.
Warum keine std::map<EnumTyp, std::string>?
-
Fellhuhn schrieb:
Hat was von deprecated Enum-Einträgen.
Warum keine std::map<EnumTyp, std::string>?
Ist vom Aufwand her auch nicht besser als switch-case.
-
Hm, okay. Sowas? Gerade beim Googlen drüber gestolpert:
#define MY_LIST \ X(foo), \ X(bar), \ X(baz) #define X(x) x enum eMyEnum { MY_LIST }; #undef X #define X(x) #x const char *szMyEnum[] = { MY_LIST }; #undef X
-
unskilled schrieb:
Die switch-Variante geht aber halt auch nicht immer...
enum x { A, B, C = A };
Ich weiß zwar nicht mal mehr, wann das bei mir das letzte mal vorkam, aber naja...
Ich weiß noch genau, wann dieser Fall "C = A" bei mir vorkam. Und das ich ihn nicht gelöst habe. Wenn jemand eine Idee hat, heraus damit.
tschüß
Troll.Soft
-
In solch einem exotischen Fall kann man A und C nicht unterscheiden, denn sie haben einen identischen Wert. Wozu sollte man sie auch unterscheiden sollen? A ist C, und C ist A.
-
Janjan schrieb:
In solch einem exotischen Fall kann man A und C nicht unterscheiden, denn sie haben einen identischen Wert. Wozu sollte man sie auch unterscheiden sollen? A ist C, und C ist A.
Identischer Wert muss nichts heißen. Bei
int a = 0, b = a;
kann ich a und b über &a und &b auch unterscheiden. Bei enum-Werten geht das aber nicht, da sie nur symbolische Kostanten sind und keine Adresse besitzen.
-
ipsec schrieb:
Janjan schrieb:
In solch einem exotischen Fall kann man A und C nicht unterscheiden, denn sie haben einen identischen Wert. Wozu sollte man sie auch unterscheiden sollen? A ist C, und C ist A.
Identischer Wert muss nichts heißen. Bei
int a = 0, b = a;
kann ich a und b über &a und &b auch unterscheiden. Bei enum-Werten geht das aber nicht, da sie nur symbolische Kostanten sind und keine Adresse besitzen.In dem Fall sind a und b aber Unterschiedliche Dinge. Bei A und C vom Enum nicht.
-
Hm, mit variadic macros könnte man was machen, wenn ich nur wüsste wie man bei __VA_ARGS__ aus jedem Element ein String macht wie es bei #element geht... hmm...
-
Vielleicht sollten wir uns darüber unterhalten, welche genauen Anforderungen an die Enumeration gestellt werden. Die fett geschriebenen wurden bisher genannt, ich habe ein paar weitere mögliche aufgelistet:
- Keine Codeduplizierung bei der Definition
- Konvertierbarkeit zu Strings
- Implizite/Explizite Konvertierbarkeit (von und) zu Ganzzahlen
- Compilezeitfehler bei Zugriff auf nicht existenten Enumerator
- Iteration durch alle Enumeratoren
- ...
Je mehr Kriterien erfüllt werden müssen, desto mühsamer wird natürlich eine Implementierung. Praktisch wäre auch ein vollständiges (und dennoch möglichst kleines) Beispiel, welches zeigt, was das
enum
alles leisten soll.
-
Da ist es wohl am einfachsten die gewünschen Enums in einer extra Datei zu verwalten und sich von einem Skript zusammenschustern zu lassen.
-
Toll wäre es, wenn man Enums ähnlich wie in Ada hätte.
Die haben folgende Eigenschaften:
Definitiontype My_Enum is (Red, Green, Blue); --Typdefinition --fuers Hardwarenahe ist das hier toll: for My_Enum'Size use 8; --My_Enum ist 8 Bit gross... for My_Enum'Alignment use 1; --...und wird an 1 Byte Grenzen aligned. for My_Enum use(Red => 1, Green => 2, Blue => 4); --Speicherrepraesentation festlegen
Konvertierbarkeit von Enum zu String und zurück:
Enum : My_Enum := Green; Str : String := My_Enum'Image(Enum); --Str enthaelt String "Green" ... Enum := My_Enum'Value("Red"); --Aus String: Enum jetzt Red
Unerscheidung zwischen interner Repräsentation (numerischer Wert im Speicher) und externer Repräsentation (siehe oben).
Iterierbarkeit über Enumerations:
for E in My_Enum'Range loop --iteriert über alle Elemente im Enum ... end loop;
Arrays von Enums:
type My_Enum_Array is array(My_Enum) of Integer; --Integer Array mit Indizes Red, Green, Blue Array : My_Enum_Array; ... Array(Green) := 10; --geht auch ganz toll mit der Schleife ueber den Range...
Es geht noch mehr, aber das sind die praktischten Eigenschaften.
-
Bleib mir weg mit Ada... so toll manche der Features auch sein mögen, alleine bei den kleinen Schnipseln die du gespostet hast, bekomm ich wieder Kopfschmerzen und Schweißausbrüche.