Javas byte in C++(11) - ein char-Wrapper



  • Kellerautomat schrieb:

    Ich glaube, die sind laut Standard nicht definiert.

    ->

    Bashar schrieb:

    Leider doch. 27.6.1.2.3§10, 27.6.2.5.4 (C++98)



  • Die sind aber im namespace std...



  • Na dann. Wo ist dann das Problem? Operatoren überladen und fertich.


  • Mod

    dot schrieb:

    Die sind aber im namespace std...

    Die Streamklassen auch...



  • ODR ist kein Problem eben wegen std:: vs. ::.

    Es "dürfte" nicht kompilieren, weil der std::operator << über ODL gefunden wird, und es daher ambiguous sein sollte.

    Es kompiliert trotzdem, weil der std::operator << ein Template ist, und bei der Overload-Resolution non-Template gegenüber Template vorgezogen wird.

    Sobald man die eigenen Operatoren auch zu Templates macht schnalzt es auch wie erwartet:

    http://ideone.com/jz6ik

    Kellerautomat schrieb:

    Na dann. Wo ist dann das Problem? Operatoren überladen und fertich.

    Ich sehe es schoh als Problem, wenn es in der Standard-Library einen passenden Operator gibt, der gefunden wird, aber nicht das tut was man will.
    Dadurch hast du nämlich keine Möglichkeit dahinterzukommen, wenn irgendwo Code kompiliert wird, der die eigenen Operatoren nicht "sieht" - weil das entsprechende File nicht inkludiert wurde. Der Compiler meldet nix, das Ergebnis ist aber falsch.

    Alles bäh.



  • Man hätte von Anfang an Zeichentypen und Integertypen etwas separieren sollen.
    char ist die Kurzform für Charakter oder? Wieso speichere ich kleine Zahlen als "Zeichen"? Was wäre, wenn ein exotischer Rechner existieren würde, der Zeichen aus irgendwie nicht numerisch Speichert, sondern zb spezielle Zeichenregister hat?

    Man hätte ja zb einem Typen small einführen können. wchar_t nutzt ja auch niemand als Integerersatz.



  • Ethon schrieb:

    Man hätte von Anfang an Zeichentypen und Integertypen etwas separieren sollen.

    Das "Problem" was wir hier haben betrifft lediglich die Implementierung der stream Klassen und sonst nichts.

    Mit boost::format oder printf, etc. gibt es dieses "Problem" garnicht.
    Und auch die stream Klassen bieten eine Loesung dafuer an: iomanip



  • Ich verstehe trotzdem nicht, wieso man kleine Zahlen als "Zeichen" speichert.



  • Ethon schrieb:

    Ich verstehe trotzdem nicht, wieso man kleine Zahlen als "Zeichen" speichert.

    Tut man das!?



  • dot schrieb:

    Ethon schrieb:

    Ich verstehe trotzdem nicht, wieso man kleine Zahlen als "Zeichen" speichert.

    Tut man das!?

    Ein Character ist ein Zeichen oder etwa nicht?
    Meiner Meinung nach nutzt man Implementierungdetails aus, wenn man einen char für etwas anderen nutzt.



  • Ethon schrieb:

    dot schrieb:

    Ethon schrieb:

    Ich verstehe trotzdem nicht, wieso man kleine Zahlen als "Zeichen" speichert.

    Tut man das!?

    Ein Character ist ein Zeichen oder etwa nicht?
    Meiner Meinung nach nutzt man Implementierungdetails aus, wenn man einen char für etwas anderen nutzt.

    Nein, das ist falsch. Ein char ist einfach ein Byte. Oft ist es praktisch dieses Byte als Buchstabe zu interpretieren, wie es zB die io stream library macht - aber das macht nur die io stream library.

    wenn ich ein
    cout<< format("%d") % 'a';
    mache, bekomme ich eine Zahl als Ergebnis.

    Es ist einfach nur oft praktisch wenn man cout<<'a'; macht, dass ein a ausgegeben wird - deshalb ist das bei der iostream library der Fall. Es hindert dich aber nichts daran eine Library zu schreiben wo das nicht der Fall ist.



  • Ethon schrieb:

    dot schrieb:

    Ethon schrieb:

    Ich verstehe trotzdem nicht, wieso man kleine Zahlen als "Zeichen" speichert.

    Tut man das!?

    Ein Character ist ein Zeichen oder etwa nicht?

    Ja, "Character" bedeutet "Zeichen", aber ein char ist ein integer...



  • Ethon schrieb:

    Man hätte von Anfang an Zeichentypen und Integertypen etwas separieren sollen.
    char ist die Kurzform für Charakter oder? Wieso speichere ich kleine Zahlen als "Zeichen"? Was wäre, wenn ein exotischer Rechner existieren würde, der Zeichen aus irgendwie nicht numerisch Speichert, sondern zb spezielle Zeichenregister hat?

    Man hätte ja zb einem Typen small einführen können. wchar_t nutzt ja auch niemand als Integerersatz.

    Genau dafür hätte man ja die (befremdliche) Trennung char/signed char/unsigned char verwenden können (sind ja bekanntlich 3 verschiedene Typen, im Gegensatz zu short/int/long/long long wo es nur je 2 verschiedene Typen gibt).
    Dann hätte die "Dreiteilung" nämlich einen Sinn: signed char und unsigned char werden als Zahl interpretiert, und char als Zeichen.

    Würde mich mal interessieren warum das nicht gemacht wurde. Kann mir nämlich grad keinen wirklich guten Grund vorstellen.



  • hustbaer schrieb:

    Würde mich mal interessieren warum das nicht gemacht wurde. Kann mir nämlich grad keinen wirklich guten Grund vorstellen.

    Weil es Aufwand ist der nichts bringt.

    Natuerlich waere es technisch feiner wenn es so waere - aber in der Praxis ist das kein Thema. Deshalb findet sich vermutlich auch niemand der dafuer ordentliche vorschlaege unterbreitet.



  • Shade Of Mine schrieb:

    wenn ich ein
    cout<< format("%d") % 'a';
    mache, bekomme ich eine Zahl als Ergebnis.

    Und was kommt raus wenn man

    unsigned char uc = 123;
    cout<< format("%1%") % uc;
    

    macht?

    Es ist einfach nur oft praktisch wenn man cout<<'a'; macht, dass ein a ausgegeben wird - deshalb ist das bei der iostream library der Fall.

    'a' ist ein char . char s sollen natürlich als Zeichen ausgegeben werden. Aber warum zum Geier werden signed char und unsigned char als Zeichen ausgegeben?

    Es hindert dich aber nichts daran eine Library zu schreiben wo das nicht der Fall ist.

    Sinnfreier Beitrag. Klar kann man alles selber schreiben.
    Man darf aber auch mal fragen warum was so ist wie es ist. Bzw. anmerken dass es doof ist so wie es ist.
    Und das ist es.
    Also doof.
    So wie es ist.



  • hustbaer schrieb:

    Sinnfreier Beitrag. Klar kann man alles selber schreiben.
    Man darf aber auch mal fragen warum was so ist wie es ist. Bzw. anmerken dass es doof ist so wie es ist.
    Und das ist es.
    Also doof.
    So wie es ist.

    Es ist kein bisschen doof. Das verhalten ist wahnsinnig praktisch. Denn wenn wir char immer automatisch als int ausgeben wuerden, wuerdest du recht schnell sehen dass das ziemlich nervig wird wenn du mit strings hantieren willst.

    Fuer die wenigen situationen wo man es anders haben will gibt es die richtigen Tools.

    Deshalb nochmal:
    dass ein char oft als Buchstabe interpretiert wird (merke: Interpretiert, er ist keiner, er wird noch als einer interpretiert) ist enorm praktisch und spart viel Arbeit. Deshalb macht man es in der Regel (merke: in der Regel, also meistens aber nicht immer) so. Es gibt aber keinen Zwang. Die Libraries muessen eins von beiden machen - das ist nunmal so. Und sie machen das, was meistens besser ist. Gleichzeitig bieten sie aber auch eine Moeglichkeit an es anders zu haben wenn man denn will.

    Und es spricht nichts gegen eine Library die es standardmaessig andersherum macht. Bis auf, dass sie enorm unpraktisch waere.

    Man muss naemlich die Konsequenzen betrachten. Nur sagen: es waere toll wenn immer das passiert was ich will - das ist kurzsichtig.

    Andere Sprachen umgehen das Problem, indem sie einen string als primitiven Typ haben und 'a' ist dann ein string der laenge 1. Das funktioniert in C++ aber nicht.



  • Nur um es noch mal klar zu machen: char ist und wird als integraler Skalar behandelt. BIS auf die Ein/Ausgabe.

    Ich fand aber dieses Problem gerade zum kotzen. Ich kann doch nicht einfach so

    for(char a(65);a < 70;++a)
          //....
    

    schreiben, wenn ich weiß, dass es nicht intern 65, 66, 67, 68, 69, 70 wird sondern
    'A', 'B', 'C', 'D', 'E', 'F'. Das ist eben ein Tick von mir. Wenn ich nicht den Gedanken hätte, wäre alles im Lot.

    Ich dachte, die Raumfolgearithmetik (also das Zweierkomplement) funktioniert auch übertragbar zwischen den Skalaren. Ist dem nicht so?

    hustbaers Vorschlag finde ich richtig. char wird eigentlich nur als Zeichen benutzt, wenn man es so schreibt. Wenn ich explizit die Vorzeichenbehaftung angebe, dann ist doch klar dass ich es als integralen Zähler o. ä. verwenden will.. 😕


  • Mod

    Hacker schrieb:

    Nur um es noch mal klar zu machen: char ist und wird als integraler Skalar behandelt. BIS auf die Ein/Ausgabe.

    Ich fand aber dieses Problem gerade zum kotzen. Ich kann doch nicht einfach so

    for(char a(65);a < 70;++a)
          //....
    

    schreiben, wenn ich weiß, dass es nicht intern 65, 66, 67, 68, 69, 70 wird sondern
    'A', 'B', 'C', 'D', 'E', 'F'. Das ist eben ein Tick von mir. Wenn ich nicht den Gedanken hätte, wäre alles im Lot.

    Ich dachte, die Raumfolgearithmetik (also das Zweierkomplement) funktioniert auch übertragbar zwischen den Skalaren. Ist dem nicht so?

    hustbaers Vorschlag finde ich richtig. char wird eigentlich nur als Zeichen benutzt, wenn man es so schreibt. Wenn ich explizit die Vorzeichenbehaftung angebe, dann ist doch klar dass ich es als integralen Zähler o. ä. verwenden will.. 😕

    😕 Das ist mir zu kryptisch.
    Verstehe auch das Problem generell nicht.
    Man zeige bitte realistischen Code, der komplexer wird, weil Zeichen als Zeichen ausgegeben werden.



  • camper schrieb:

    😕 Das ist mir zu kryptisch.

    Du bist camper. 😮
    Ich hab auch nicht zu deinem TMP-Zeug tl:dr geschrieben.



  • Shade Of Mine schrieb:

    hustbaer schrieb:

    Sinnfreier Beitrag. Klar kann man alles selber schreiben.
    Man darf aber auch mal fragen warum was so ist wie es ist. Bzw. anmerken dass es doof ist so wie es ist.
    Und das ist es.
    Also doof.
    So wie es ist.

    Es ist kein bisschen doof. Das verhalten ist wahnsinnig praktisch. Denn wenn wir char immer automatisch als int ausgeben wuerden, wuerdest du recht schnell sehen dass das ziemlich nervig wird wenn du mit strings hantieren willst.

    (...)

    Ich hab's jetzt glaub ich erst 2x geschrieben, also zum 3. Mal: char , signed char und unsigned char sind bereits drei verschiedene Typen.
    Was wäre nun so unpraktisch daran wenn signed char und unsigned char als Integers ausgegeben würden, und nur char weiterhin als Zeichen?

    Aufwand würde das auch keinen darstellen, alles was dafür nötig wäre ist zwei Spezialisierungen des Stream-Insert Operators auf die "Integer" Variante umzubiegen. Die muss es sowieso schon geben, für die anderen Typen ( short , int etc.), die eben als Integer ausgegeben werden.
    Und das selbe nochmal für den Stream-Extraction Operator.


Anmelden zum Antworten