enum zu string



  • Finde ich z.B. für Debug-Ausgaben sinnvoll!



  • finder schrieb:

    Finde ich z.B. für Debug-Ausgaben sinnvoll!

    Jemals was von Debugger gehört? ^^

    Aber ja, das ist ein Argument.



  • Ich empfinde diese Variante als wesentlich sinniger:

    enum T
        {
            A = 0,
            B,
            C
        };
    
        char names[] =
        {
            'A',
            'B',
            'C'
        };
    


  • 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 das A = 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.


Anmelden zum Antworten