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.


Anmelden zum Antworten