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, istostream& 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, dassconst 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ürNewlines
geschrieben hast?operator<<( std::cout, Newlines( 25 ) );
-
Upps.
Problem geklärt.