2014-05-10 9 views
23

Ich lerne C++ und habe mich nie mit Streams befasst. Ich würde die Notation zu erwarten haben:Warum werden C++ - Iostreams immer links zugewiesen?

std::cout << "foo"; 
char foo << std::cin; 

Ich bin sicher, es gibt einen guten Grund, es std::cin >> foo ist. Was ist es?

+1

diesen Code einfügen 'char & operator << (char & dst, std :: istream & src) {src >> dst; Rückkehr dst; } 'in deine und spiele mit' char a; ein

+1

Eine praktische Möglichkeit, sich an den Unterschied zu erinnern, ist, dass der Bediener in die Richtung des Datenflusses zeigt. :) – thedayturns

Antwort

39

Es hat mit der Assoziativität der < < und >> Operatoren zu tun.

Sie waren ursprünglich nur für Bit-Verschiebung, wo sie assoziativ bleiben. Die Operatorassoziativität bleibt gleich bei Überlastung (sonst würde der Code unmöglich sein, zu analysieren):

Wenn Sie

int a, b ; 
a << b << cin 
tun

würden Sie

(a << b) << cin 

eine Bit-Verschiebung erhalten und und Eingabe

Dies ist der Grund, warum die Standardbibliothek so funktioniert.

+14

Der Meta-Punkt zu machen ist, dass Streams Teil der Bibliothek sind, nicht die Basissprache, so dass die Sprache keine Unterstützung für einen eindeutigen Operator mit einer Syntax bietet, die vollständig der Semantik entspricht. '' '' ist tatsächlich buchstäblich eine Überladung des Bit-Shift-Operators, nicht nur eine Sprachfunktion, die auf zwei verschiedene Arten verwendet wird. –

13

a << ba >> b und sind nur für Kürzel:

operator<<(a,b) 

und

operator>>(a,b) 

(oder die Mitgliedsfunktions-Äquivalente).

Das heißt, sie sind nur Anrufe zu bestimmten Funktionen. Es passiert einfach, dass die C++ - Standardbibliothek operator<< überlastet, um ein Ausgabe-Streaming an ostream s und operator>> durchzuführen, um ein Eingabe-Streaming von istream s durchzuführen.

Diese Funktionen sind nur überlastet, um den Stream auf der linken Seite zu haben.

Es gibt zwei Gründe für diese Entscheidung. Die erste ist die Einfachheit der Notation (da es nur einen Weg gibt, die Operanden zu sortieren, gibt es weniger Zweideutigkeiten bezüglich der Bedeutung eines bestimmten Codes, und es ist weniger notwendig, eine große Anzahl verschiedener Überladungen zu implementieren, wenn die Standardbibliothek erweitert wird eine zusätzliche Klasse unterstützen). Die zweite ist, dass << und >> assoziativen gelassen werden, und so:

int a, b; 
a << b << cin; 

werden würde:

(a << b) << cin; 

während:

int a, b; 
cin >> b >> a; 

korrekt wird:

(cin >> b) >> a; 
3

Es ist so, dass Sie gezwungen sein werden, die Konsole auf der linken Seite so zu platzieren, wie Gott es beabsichtigt hat! :)

Es hat tatsächlich mit etwas zu tun, das Überlastung des Operators genannt wird. Wenn du gerade C++ lernst, hast du das wahrscheinlich noch nicht behandelt, also füge das ein, was ich unter "Zeug, das ich später bekomme" sagen werde.

C++ lebt auf C. In C << und >> sind nur Bit-Shift-Operatoren. In C++ kann es mehr sein. std:cout << foo ist NICHT C, es ist C++. Der Grund, warum es C++ ist, liegt darin, dass das Objekt std::cout den Operator << überlädt, um etwas anderes als Bitverschiebung zu bedeuten.

Mit anderen Worten, << bedeutet nur senden foo zu cout, weil cout sagte, das ist was es bedeutet. << ist in der Tat eine Funktion für die Klasse cout.

Es ist fast so, als ob Sie sagten std::cout->sendThatToMe(foo).

In dieser ganzen Angelegenheit foo ist nur ein glücklicher Parameter entlang für die Fahrt, die kein Mitspracherecht hat, was << bedeutet. Deshalb kannst du es nicht anders machen. Wenn Sie es getan haben würde, als ob Sie diese sagten:

foo->sendMeToThat(std::cout). 

die gemacht werden können arbeiten, wenn Sie diese Funktion hinzuzufügen (auch die >> Betreiber wirklich) zu jedem stinkenden Objekt, das Sie jemals die senden mögen Konsole. Oh, und viel Glück, wenn es mit Primitiven geht.

Also, während ich denke, dass es sehr gute Stil Gründe gibt, die Konsolen-Sachen auf der linken Seite zu behalten, gibt es tatsächlich einen technischen Grund, dass es so sein muss. Das liegt daran, dass Operatoren, die überladen sind, bereits assoziativ sind. Seit sie in den alten C-Tagen benutzt wurden, um Bits zu verschieben. Überladen sie bietet keine Chance, ihre Assoziativität zu ändern.

0

Das ist genau so, wie sie funktionieren sollen. Ich denke, dies wurde getan, um Eingabeoperationen (>>) von Ausgabeoperationen (< <) klar zu unterscheiden.
Wenn Sie den << Operator in dieser extravaganten Art und Weise überlasten (als Captain in den Kommentaren Offensichtliche vorgeschlagen):

template<typename T> 
std::istream& operator<<(T& data , std::istream& is) 
{ 
    is >> data; 
    return *this; 
} 

Es weniger klar sein wird, wenn die operaton Eingang oder Ausgang (mit std::cin std::cout seine einfachen, aber was über zwei Ströme genannt file1 und file2, eine zum Lesen und eine für writting):

a << std::cin; 
std::cout << a; 

a << file; 
file << a; 
Verwandte Themen