cout.operator ...



  • Hallo,
    der Grund steht für den Template-Kenner mit zusätzlichen VC-Kentnissen etwas versteckt bereits in meinem oberen Beitrag 🙂

    Die freie Funktion operator<< die einen const char* ausgeben kann ist eine *Template*-Funktion und sieht beim VC so aus:

    template<class _E, class _Tr> inline
    basic_ostream<_E, _Tr>& operator<<(basic_ostream<_E, _Tr>& _O, const _E *_X)
    

    Bei einem:

    cout << "Hallo";
    

    wird _E zu char und _Tr zu char_traits<char>. Der Parameter _X ist also vom Typ
    const char*.

    Bei der Herleitung von Templateparameter finden aber grundsätzlich keine Benutzerdefinierte Konvertierungen statt.
    Der Aufruf:

    DeineStringKlasse s;
    cout << s;
    

    kann nicht zum Aufruf des entsprechenden Operators führen, da s nicht vom Typ const char* ist und der Konvertierungsoperator nicht berücksichtigt wird.

    Die Memberfunktion operator << die ein void*-erwartet ist kein Template sondern eine normale Funktion. Hier werden selbstverständlich alle erlaubten Konvertierungen durchgeführt.

    DeineStringKlasse s;
    cout << s;
    

    Hier wird also erst s nach char* mittels einer Benutzer-definierten Koonvertierung gewandelt und dann char* nach void* durch eine Standardkonvertierung.

    Bis hierhin ist der VC im Recht. Allerdings schreibt der Standard zusätzlich zu der oben genannten freien Funktion noch eine Funktion:

    [code type="c++"]
    template<class _E, class _Tr> inline
    basic_ostream<_E, _Tr>& operator<<(basic_ostream<_E, _Tr>& _O, const char* )
    

    vor. Da hier der zweite Parameter nicht von einem Templateparameter abhängt, werden für diesen auch benutzerdefinierte Konvertierungen durchgeführt.

    DeineStringKlasse s;
    cout << s;
    

    würde also diese Funktion aufrufen.

    Der VC versäumt allerdings die Bereitstellung einer solchen Funktion.



  • Was muss man denn nun machen, damit cout.operator << ("Hallo Welt") beim MSVC++ den String "Hallo Welt" ausgibt? 😕



  • operator<<(cout,"Hello World");
    aufrufen?



  • Man löst dieses Problem dann, indem man auch den <<-operator überlädt?



  • int main()
    {
    
      string s = "Hallo3";
    
      cout << "Hallo" << endl;
      cout.operator <<(L"Hallo1") << endl;
      cout.operator <<(L"Hallo2") << endl;
      cout.operator <<(s.c_str()) << endl;
      operator <<(cout,"Hallo4");
    
      cin.get();
      return 0;
    }
    

    😕 🙄



  • Man löst dieses Problem dann, indem man auch den <<-operator überlädt?

    Falls du noch dein Stringproblem meinst.
    Meine Lösung wäre:
    1. Man entfernt umgehend die implizite Konvertierung und ersetzt sie durch eine explizite Methode (à la c_str). Implizite Konvertierungen bringen häufig Probleme mit sich und es lohnt sich in dieser Situation einfach nicht diese in Kauf zu nehmen. Außerdem orientiere ich mich gerne an Designs, die sich bereits etabliert haben (std::string verzichtet z.B. auf eine implizite Konvertierung nach char*. Die MFC-Klasse CString hat eine solche, die Klassenbibliothek gilt aber nirgends auch nur halbwegs als Beispiel für gutes Design).

    2. Zusammen mit der Klasse liefert man auch einen operator<< der ein Objekt der Klasse ausgibt.

    Fertig. Weniger Mehrdeutigkeiten, weniger Überaschungen.



  • Original erstellt von HumeSikkins:
    **Die MFC-Klasse CString hat eine solche, die Klassenbibliothek gilt aber nirgends auch nur halbwegs als Beispiel für gutes Design).
    **

    Doch 🙂 Bei Marcus als Beispiel fürs Refcounting 🙂

    Naja, was kann es bei impliziten KOnvertierungen noch für Probleme geben? CString hat aber dazu ja auch noch ne Funktion analog zu c_str: GetBuffer.

    [ Dieser Beitrag wurde am 25.06.2003 um 22:05 Uhr von dEUs editiert. ]



  • Ich empfinde C++ an dieser Stelle als unbefriedigend und übermäßig kompliziert. Manche denken sogar, "<<" und "operator <<" seien das Gleiche. Offenbar gibt es hier zusätzlich Ungereimtheiten von Compiler zu Compiler.



  • siehe auch folgenden Wirrwarr: http://www.microsoft.com/msj/archive/SD71.aspx



  • Ich empfinde C++ an dieser Stelle als unbefriedigend und übermäßig kompliziert.

    Aha. Ich nicht. Was heißt das jetzt? Und wichtiger. Wie würdest du es besser machen. Natürlich unter den Bedingungen die für C++ gelten (z.B. maximale C-kompatibilität).

    Manche denken sogar, "<<" und "operator <<" seien das Gleiche

    Manche denken sogar, void main wäre Standard.
    Manchmal hilft *lernen* viel mehr als denken. C++ erfordert in vielen Bereichen schlicht und einfach wissen. Intuition allein kommt man in dieser Sprache nicht weit.

    siehe auch folgenden Wirrwarr

    Wieso wirrwarr? Dieses Thema wird in jedem *guten* Anfängerbuch erwähnt und erklärt. Immer auch mit der entsprechenden Lösung.

    Natürlich ist C++ komplex (aber das ist eigentlich jede mir bekannte Sprache general-purpose-Sprache).
    Auch besonders im Bereich der Auflösung von Funktionsaufrufen.
    Deshalb lernt man C++ auch nicht in 21 Tagen oder am Wochenende. Zumindest wenn man mehr als nur "Hello World" will.


Anmelden zum Antworten