enum in Stream schicken?



  • Hallo,

    kann ich folgerndermaßen sicher für einen eigenen enum-Typen mit Streams arbeiten?

    enum Test {A, B, C};
    
    ostream& operator<<(ostream& os, const Test t)
    {
        return os << int(t);
    }
    
    istream& operator>>(istream& is, Test& t)
    {
        int x;
        is >> x;
        t = Test(x);
        return is;
    }
    

    ?



  • Ich persönlich würde ja std::underlying_type nehmen - wobei man bei "char" eventuell aufpassen muss.



  • Ja, das funktioniert. Und in C++11 sollte man wohl scoped enumerations verwenden (und entsprechend einen expliziten cast).



  • Sone schrieb:

    und entsprechend einen expliziten cast

    Das hat Eisflamme ja schon. Ich würde allerdings static_cast verwenden.



  • Nexus schrieb:

    Sone schrieb:

    und entsprechend einen expliziten cast

    Das hat Eisflamme ja schon. Ich würde allerdings static_cast verwenden.

    Ich auch, wusste aber nicht, dass das ein expliziter ist! Danke.



  • Nennt sich Function-Style-Cast und verhält sich wie der C-Cast, biegt also alles um. Finde ich etwas unglücklich, da er wie ein harmloser Konstruktoraufruf aussieht -- gerade hinter typdef s.



  • Nexus schrieb:

    Finde ich etwas unglücklich, da er wie ein harmloser Konstruktoraufruf aussieht -- gerade hinter typdef s.

    Eben, dass dachte ich auch, dass es einfach direct initialization ist...



  • Also ich bin mir jetzt nicht sicher, aber soweit ich diese Form kannte, entspricht das eher einem static_cast als einem c-cast. Hier wäre mir eine weitere Meinung oder ein Standard-zitat sehr recht.

    Ein c-cast ist ja geradezu verpöhnt, aber dieser cast war für mich immer noch in ordnung.



  • Eisflamme schrieb:

    Also ich bin mir jetzt nicht sicher, aber soweit ich diese Form kannte, entspricht das eher einem static_cast als einem c-cast. Hier wäre mir eine weitere Meinung oder ein Standard-zitat sehr recht.

    Bitte sehr:

    5.2.3 Explicit type conversion (functional notation) schrieb:

    A simple-type-specifier (7.1.6.2) or typename-specifier (14.6) followed by a parenthesized expression-list constructs a value of the specified type given the expression list. If the expression list is a single expression, the type conversion expression is equivalent (in definedness, and if defined in meaning) to the corresponding cast expression (5.4).

    5.4 Explicit type conversion (cast notation) schrieb:

    The result of the expression (T) cast-expression is of type T. The result is an lvalue if T is an lvalue reference type or an rvalue reference to function type and an xvalue if T is an rvalue reference to object type; otherwise the result is a prvalue.

    Du siehst also, die Ausdrücke sind äquivalent. Kannst du auch ganz leicht testen, indem du so einen int* in einen double* castest, das kompiliert anstandslos.



  • Hallo Eisflamme,

    wir benutzen in unserer Applikation tatsächlich zum Teil aussagekräftige Strings, um enum-Werte zu speichern. Mit dem Hintergrund, dass die Dateien, in die diese abgelegt werden, auch von Menschen gelesen und ggf. manipuliert werden.
    Zum Einlesen benutzen wir die Funktion _Getloctxt ; eine interne Funktion in xlocnum aus den Standard-Headern von Dinkumware. Diese Funktion akzeptiert als Input ein char-Array, in dem die einzelnen enum-Ausdrücke mit Trennzeichen abgelegt sind. Wobei das erste Zeichen als Trennzeichen definiert, also frei wählbar ist.
    Seien die drei enum-Strings "AA", "ein-B" und "Zeh", dann könnte man hier ":AA:ein-B:Zeh" mitgeben. Findet _Getloctxt einen der drei Strings so wird ein Index zurückgegebn (hier 0, 1 oder 2) ansonsten ein negativer Wert.

    Gruß
    Werner



  • Hallo,

    cooky:
    Alles klar, vielen Dank. 🙂 Dann hatte ich das total falsch im Kopf.

    Werner:
    Uh, okay, das klingt interessant. Ich denke, die Cast-Variante genügt mir dann jedoch, da der menschliche Benutzer in den Dateien eigentlich auch nichts ändern können soll. Ich caste dann lieber korrekt und nutze diese Variante. Trotzdem danke 🙂



  • Du musst halt auch aufpassen, dass du keine Enumeratoren entfernst und neue nur am Ende einfügst, da du sonst die Zuordnung zu int s durcheinander bringst.



  • Stimmt, danke! Zum Glück sind die enums, die ich gerade gebrauche, fix.


Log in to reply