Sia intenzionalmente che per caso, hai <<alla fine della prima linea di uscita, dove probabilmente intendevi ;. Quindi essenzialmente hai
cout << "2+3 = "; // this, of course, prints "2+3 = "
cout << cout; // this prints "1"
cout << 2 + 3; // this prints "5"
cout << endl; // this finishes the line
Quindi la domanda si riduce a questo: perché cout << cout;stampa "1"?
Questo risulta essere, forse sorprendentemente, sottile. std::cout, tramite la sua classe base std::basic_ios, fornisce un determinato operatore di conversione di tipo che deve essere utilizzato in un contesto booleano, come in
while (cout) { PrintSomething(cout); }
Questo è un esempio piuttosto scarso, poiché è difficile far fallire l'output, ma in std::basic_iosrealtà è una classe di base sia per i flussi di input che di output e per l'input ha molto più senso:
int value;
while (cin >> value) { DoSomethingWith(value); }
(esce dal ciclo alla fine del flusso o quando i caratteri del flusso non formano un numero intero valido).
Ora, la definizione esatta di questo operatore di conversione è cambiata tra le versioni C ++ 03 e C ++ 11 dello standard. Nelle versioni precedenti, era operator void*() const;(tipicamente implementato come return fail() ? NULL : this;), mentre nelle versioni più recenti explicit operator bool() const;(tipicamente implementato semplicemente come return !fail();). Entrambe le dichiarazioni funzionano bene in un contesto booleano, ma si comportano diversamente quando (mis) vengono utilizzate al di fuori di tale contesto.
In particolare, in base alle regole C ++ 03, cout << coutsarebbe interpretato come cout << cout.operator void*()e stampare un indirizzo. Secondo le regole C ++ 11, cout << coutnon dovrebbe essere compilato affatto, poiché l'operatore è dichiarato explicite quindi non può partecipare a conversioni implicite. Questa era in realtà la motivazione principale per il cambiamento, che impediva la compilazione di codice senza senso. Un compilatore conforme a entrambi gli standard non produrrebbe un programma per la stampa "1".
Apparentemente, alcune implementazioni C ++ consentono di mescolare e abbinare il compilatore e la libreria in modo tale da produrre risultati non conformi (citando @StephanLechner: "Ho trovato un'impostazione in xcode che produce 1, e un'altra impostazione che produce un indirizzo: dialetto della lingua c ++ 98 combinato con "Libreria standard libc ++ (libreria standard LLVM con supporto c ++ 11)" produce 1, mentre c ++ 98 combinato con libstdc (libreria standard gnu c ++) fornisce un indirizzo; "). Puoi avere un compilatore in stile C ++ 03 che non comprende gli explicitoperatori di conversione (che sono nuovi in C ++ 11) combinato con una libreria in stile C ++ 11 che definisce la conversione come operator bool(). Con un tale mix, diventa possibile cout << coutessere interpretato come cout << cout.operator bool(), che a sua volta è semplicemente cout << truee stampa "1".
;alla fine della prima riga di output, no<<. Non stai stampando ciò che pensi di stampare. Stai facendocout << cout, che stampa1(usacout.operator bool(), credo). Quindi5(da2+3) segue immediatamente, facendolo sembrare il numero quindici.