Eine simple Frage...
-
Was ist eigentlich std::endl?
Es ist ja keine Methode denn
a) fehlen die Klammern beim Aufruf und b) würde der Puffer ja geleert bevor er gefüllt wird. Aber was ist es denn?Aus der Definition
_CRTIMP inline basic_ostream<char, char_traits<char> >& __cdecl endl(basic_ostream<char, char_traits<char> >& _O) { _O.put('\n'); _O.flush(); return (_O); }
kann ich mir nicht wirklich viel nehmen und bin jetzt ziemlich verwirrt.
-
endl ist offensichtlich eine Funktion, der ein ostream-Argument übergeben wird, und die dann auf diesem ostream ein newline ausgibt und ihn flusht. also könnte man endl(cout); schreiben, wenn man lustig wär.
warum kann man dann cout << endl; schreiben? nun, ostream hat einen operator<<, der genau solche Funktionen annimmt. der könnte etwa so implementiert sein:
ostream& operator<<(ostream& os, ostream& (*manip)(ostream&)) { manip(os); return os; }
(isser natürlich in wirklichkeit nicht. das dürfte ein template sein, das auch mit funktionsobjekten klarkommt)
dh wenn du cout << endl; schreibst, ruft der operator<< als erstes endl(cout) auf, und gibt dann das veränderte cout zurück.
-
Aber würde dann nicht der Puffer zuerst geflusht?
Beispiel:
std::cout << "Was " << "auch " << "immer." << std::endl;
Wie wäre hier die Aufrufreihenfolge und warum?
-
einfach mal klammern setzen und nochmal überlegen:
(((cout << "was") << "zum") << "lesen") << endl;
-
Die Reihenfolge dacht ich mir, jedoch versteh ich nicht, wieso der Funtkionsaufruf als letztes kommt.
-
Eine Funktion kann erst aufgerufen werden, wenn alle ihre Argumente berechnet sind (eager evaluation). Also kann operator<< in (... ausdruck ...) << endl; erst dann aufgerufen werden, wenn der linke ausdruck berechnet wurde. der wiederum sieht so aus: (... ausdruck2 ...) << "lesen". geht wieder nicht. das ganze geht so lange, bis der linke ausdruck einfach cout ist: cout << "was". das wird ausgewertet, ergebnis ist wieder cout. also kommt als nächstes cout << "zum". dann cout << "lesen", dann cout << endl. das ergebnis ist schon wieder cout, wird aber verworfen.
-
Danke.
Gibt es eigentlich einen Weg endl() als Member einer Klasse zu konstruieren die einen Stream kapselt?
-
Hat sich erledigt.