2014-05-10 9 views
23

Sto imparando C++ e non ho mai avuto a che fare con i flussi. Mi sarei aspettato la notazione di essere:Perché gli iostreami C++ sono sempre assegnati alla mano sinistra?

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

Sono sicuro che ci sia una buona ragione è std::cin >> foo. Che cos'è?

+1

incolla questo codice 'char & operator << (char & DST, std :: istream & src) {src >> dst; return dst; } 'nel tuo e gioca con' char a; un << std :: cin; 'un po '. Oh, potresti provare a spostare i bit in 'a'. –

+1

Un modo pratico per ricordare la differenza è che l'operatore punta nella direzione del flusso di dati. :) – thedayturns

risposta

39

esso ha a che fare con l'associatività degli operatori e degli operatori >>.

Inizialmente erano solo per lo spostamento di bit in cui sono rimasti associati. L'associatività dell'operatore rimane lo stesso in caso di sovraccarico (in caso contrario, il codice sarebbe impossibile da analizzare):

Se avete fatto

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

si otterrebbe

(a << b) << cin 

Uno spostamento bit e e input

Questo è il motivo per cui la libreria standard funziona come fa.

+14

Il meta-point da fare qui è che gli stream sono parte della libreria, non della lingua base, quindi la lingua non ha supporto per un operatore unico con sintassi che corrisponde completamente alla semantica. '' 'è in realtà letteralmente un sovraccarico dell'operatore di spostamento del bit, non solo una funzione del linguaggio utilizzata in due modi diversi. –

13

a << b e a >> b sono solo delle abbreviazioni per:

operator<<(a,b) 

e

operator>>(a,b) 

(o gli equivalenti membro-funzione).

Cioè, sono solo chiamate a funzioni particolari. Accade semplicemente che la libreria standard C++ sovraccarichi operator<< per eseguire lo streaming di output su ostream s e operator>> per eseguire lo streaming di input da istream s.

Queste funzioni sono sovraccariche solo per avere lo streaming sulla sinistra.

Ci sono due motivi per questa decisione. La prima è la semplicità notazionale (cioè, poiché esiste un solo modo di ordinare gli operandi, c'è meno ambiguità sul significato di ogni particolare codice, e c'è meno bisogno di implementare un enorme numero di sovraccarichi diversi quando si estende la libreria standard a supportare una classe aggiuntiva). La seconda è che << e >> sono lasciati associativa, e quindi:

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

diventerebbe:

(a << b) << cin; 

mentre:

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

diventa correttamente:

(cin >> b) >> a; 
3

È così che sarai costretto a mettere la consolle a sinistra come voleva Dio! :)

In realtà ha a che fare con qualcosa chiamato overloading dell'operatore. Se stai semplicemente imparando il C++ probabilmente non lo hai già visto, quindi archivia quello che sto per dire in "cose ​​che prenderò più tardi".

C++ vive sopra C. In C << e >> sono solo operatori bit shift. In C++ può essere di più. std:cout << foo NON è C, è C++. Il motivo è C++ è perché l'oggetto std::cout sovraccarica l'operatore << per significare qualcosa di diverso po spostamento.

In altre parole, << significa solo inviare foo a cout, perché cout ha detto che è ciò che significa. << è, in effetti, una funzione della classe cout.

E 'quasi come se lei ha detto std::cout->sendThatToMe(foo).

In questo caso intero foo è solo un parametro sfortunato lungo per la corsa che non ha voce su ciò che significa <<. Questo è il motivo per cui non puoi farlo nell'altro modo. Se avete fatto, sarebbe come se si stesse dicendo questo:

foo->sendMeToThat(std::cout). 

che può essere fatta funzionare se si aggiunge che la funzione (ben l'operatore >> davvero) per ogni oggetto puzzolente si potrebbe mai desiderare di inviare al console. Oh e buona fortuna tirandolo fuori con i primitivi.

Così, mentre penso che ci sono ragioni di stile molto buoni per voler mantenere la roba console lì a sinistra in realtà è una ragione tecnica deve essere in questo modo. È perché gli operatori in sovraccarico sono già stati associati in modo associativo. Sono stati da quando erano abituati a spostare pezzi nei vecchi C giorni. Sovraccaricarli non offre la possibilità di cambiare la loro associatività.

0

Questo è solo il modo in cui si suppone di lavorare. Penso che questo è stato fatto per distinguere chiaramente le operazioni di input (>>) da operazioni di output (< <).
Se si esegue l'overload dell'operatore << in questo modo di fantasia (come Capitan Ovvio suggerito nei commenti):

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

sarà meno chiaro se l'operaton fosse ingresso o di uscita (con std::cin std::cout la sua facile, ma cosa su due flussi definiti file1 e file2, uno per la lettura e uno per la scrittura):

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

a << file; 
file << a; 
Problemi correlati