Es ist nichts falsch daran, außer es gibt keinen überladenen < < Operator dafür definiert. Die vorhandenen Überlasten für < < erwarten einen Manipulator mit der Signatur ostream & (* fp) (ostream &).
Wenn Sie ihm einen Manipulator mit dem Typ Ostream & (* fp)() geben würden Sie einen Compiler-Fehler erhalten, da es nicht hat eine Definition für Operator < < (ostream &, Ostream & (* fp)()). Wenn Sie diese Funktionalität wünschen, müssen Sie den Operator < < überladen, um Manipulatoren dieses Typs zu akzeptieren.
Sie würden eine Definition für diese schreiben:
Ostream & ostream :: operator < < (ostream & (* m)())
Beachten Sie hier, dass nichts Magisches geschieht hier . Die Stream-Bibliotheken basieren stark auf Standard C++ - Funktionen: Überladen von Operatoren, Klassen und Referenzen.
Nun, da Sie wissen, wie Sie die Funktionen erstellen können, die Sie beschrieben, ist hier, warum wir es nicht tun:
Ohne einen Verweis auf den Strom geben wir zu manipulieren versuchen, können wir nicht auf den Strom, Änderungen verbunden mit dem letzten Gerät (cin, out, err, fstream, etc). Die Funktion (Modifier sind alle nur Funktionen mit Phantasie Namen) würde entweder eine neue Ostream, die nichts mit der links vom < Operator oder durch einen sehr hässlichen Mechanismus zu tun hatte, um herauszufinden, welche Ostream es sollte connect with else alles auf der rechten Seite des Modifiers wird es nicht zum endgültigen Gerät machen, sondern würde lieber an den ostream geschickt werden, den die Funktion/Modifier zurückgegeben hat.
Denken Sie an Ströme wie dieser
cout << "something here" << tab << "something else"<< endl;
wirklich bedeutet
(((cout << "something here") << tab) << "something else") << endl);
wo jeder Satz von Klammern ist etwas cout (schreiben, ändern usw.) und kehrt dann cout so den nächsten Satz von Klammern kann daran arbeiten.
Wenn Ihr Tab Modifikator/Funktion keinen Bezug zu einem Ostream hatte, müsste er irgendwie erraten, welche Ostream der < < Operator zur Ausführung seiner Aufgabe übrig hatte. Arbeitest du mit cour, cerr, einem Dateistrom ...? Die Interna der Funktion werden niemals erfahren, es sei denn, sie erhalten diese Information wie und warum nicht so einfach wie eine Referenz darauf.
nun wirklich den Punkt nach Hause zu fahren, lassen Sie uns sehen, was Endl wirklich ist und die überladene Version des < < Operator wir verwenden:
Dieser Operator wie folgt aussieht:
ostream& ostream::operator<<(ostream& (*m)(ostream&))
{
return (*m)(*this);
}
endl sieht wie folgt aus:
ostream& endl(ostream& os)
{
os << '\n';
os.flush();
return os;
}
der Zweck endl ist ein newli hinzufügen ne und spülen Sie den Stream und stellen Sie sicher, dass der gesamte Inhalt des internen Puffers des Streams auf das Gerät geschrieben wurde. Um dies zu tun, muss zuerst ein '\ n' in diesen Stream geschrieben werden. Es muss dann dem Stream mitteilen, dass er gespült werden soll. Die einzige Möglichkeit für endl, zu wissen, in welchen Stream geschrieben und gespült werden soll, ist, dass der Operator diese Informationen beim Aufruf an die Funktion endl weiterleitet. Es wäre so, als würde ich dir sagen, dass du mein Auto waschen sollst, aber dir auf dem vollen Parkplatz nie sagen darf, welches Auto mir gehört. Du würdest niemals deine Arbeit erledigen können. Du brauchst entweder mein Auto oder ich kann es selbst waschen.
Ich hoffe, dass es löscht
PS up - Wenn Sie mein Auto aus Versehen finden passieren Sie zu, fügen Sie es waschen.
Können Sie die Frage in Ihrem letzten Absatz klären? Ich verstehe nicht, was du meinst. –
Ich meine, dass, wenn Sie Cout schreiben << hex << a << b << endl << c; dann werden alle Zahlen in Hex-Basis angezeigt, aber wenn ich cut << 'a' << tab << 'b' << 'c' << endl; schreibe, dann wird der "Tab" nur während des Druckens von 'b wirksam ', aber nicht für' c '. – Narek
@Narek: Ihre Definition von 'Tab' druckt nur einen Tab, ändert nicht die Einstellungen des Streams wie' hex'. –