Frage zu cout ohne Infixschreibweise mit Manipulatoren



  • Hallo,

    es würde schon weiterhelfen, wenn mir jemand sagt, was aus cout << 123 << "Hallo"; ohne Infixschreibweise wird. Schreib ich nämlich nur cout.operator<<("Hallo"), bekomm ich nur ne Adresse ausgegeben, bei operator<<(cout, "Hallo") aber nicht, bei operator<<(cout, 123).operator<<("Hallo") bekomme ich ne Fehlermeldung (mehrdeutiger Funktionsaufruf) aber bei operator<<(cout, "Hallo").operator<<("Hallo") wiederum nicht (dafür aber als Ausgabe wieder "Hallo0xirgendwas"). operator<<(cout, "Hallo").operator<<(123) funktioniert komplett..
    Außerdem dachte ich dass soetwas wie operator<<(operator<<(cout, "Hallo"), 123) möglich wäre, da bekomme ich aber diesselbe Fehlermeldung. Ich hab versucht aus den Signaturen der Funktionen schlau zu werden, habs aber nicht hingekriegt. Und wenn ich dann versuche, sowas wie cout << setw(3) ohne Infix hinzuschreiben, krieg ich gar nichts mehr hin.
    Wahrscheinlich überseh ich mal wieder was total offensichtliches..

    Wäre nett, wenn da jemand Licht ins dunkle bringen würde.



  • cout.operator<<("Hallo")
    

    Der überladene operator<<, der in der ostream Klasse definiert ist, und zu deinem Parametertyp char const [6] passt, ist

    ostream& operator<< (const void* val);
    

    Klar, dass da eine Adresse ausgegeben wird 😉

    Aus

    cout << 123 << "Hallo";
    

    Wird dank ADL irgendwie sowas wie

    std::operator<<(std::cout.operator<<(123), "Hallo");
    


  • Guckst du hier: http://cplusplus.com/reference/iostream/ostream/operator%3C%3C/
    siehst du, dass const char* -Überladungen allesamt Global sind. So schauts also richtig aus:

    #include <iostream>
    using namespace std;
    int main(int argc, char** argv)
    {
        operator<<((cout.operator<<(123)), "Hallo");
    }
    

    Der innere Operator wird zuerst ausgeführt, gibt seinen Kram aus (ist eine Memberfunktion), returnt cout als Referenz und diese wird direkt für den äußeren benutzt, der den C-String ausgibt (ist eine Freie Funktion).



  • Okay, danke. Soweit so gut.

    Jetzt hab ich mir nen kleinen Manipulator gebastelt

    #include <iostream>
    
    class Newlines
    {
        int number;
    public:
        Newlines(int n) : number(n) {}
        std::ostream& operator()(std::ostream& o) const
        {
            for(int i = 0; i < number; ++i, o << '\n');
            return o.flush();
        }
    };
    
    std::ostream& operator<<(std::ostream& o,
                             const Newlines& newlines)
    {
        return newlines(o);
    }
    
    int main()
    {
        std::operator<<(std::cout, Newlines(25)); //error: cannot bind 'std::ostream {aka std::basic_ostream<char>}' lvalue to 'std::basic_ostream<char>&&'
        std::cout.operator<<(Newlines(25)(std::cout));
    }
    

    Laut "Der C++ Prorammierer" (S. 377, "2. Der Ausdruck cout << Leerzeilen(25) wird vom Compiler in die Langform operator<<(cout, Leerzeilen(25)) umgewandelt. [...]") wäre ja Zeile 23 richtig, da bekomme ich aber ne Fehlermeldung. Ist ja auch klar, laut http://cplusplus.com/reference/iostream/ostream/operator<</ gibt's keinen globalen operator<< der Funktoren aktzeptiert.. Daher hab ich das in Zeile 24 so hingeschrieben. Das funktioniert zwar, aber mir wird dann noch eine Adresse mit ausgegeben (hinter den Leerzeilen). Warum ist das so und wie gehts richtig?



  • Wieso rufst du nicht den operator<< , den du selbst für Newlines geschrieben hast?

    operator<<( std::cout, Newlines( 25 ) );
    


  • Upps.
    Problem geklärt.


Log in to reply