Ya sea intencionalmente o por accidente, tiene <<al final de la primera línea de salida, donde probablemente quiso decir ;. Entonces esencialmente tienes
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
Entonces la pregunta se reduce a esto: ¿por qué cout << cout;imprimir "1"?
Esto resulta ser, quizás sorprendentemente, sutil. std::cout, a través de su clase base std::basic_ios, proporciona un operador de conversión de cierto tipo que está destinado a ser utilizado en contexto booleano, como en
while (cout) { PrintSomething(cout); }
Este es un ejemplo bastante pobre, ya que es difícil hacer que la salida falle, pero en std::basic_iosrealidad es una clase base tanto para flujos de entrada como de salida, y para la entrada tiene mucho más sentido:
int value;
while (cin >> value) { DoSomethingWith(value); }
(sale del bucle al final de la secuencia, o cuando los caracteres de la secuencia no forman un número entero válido).
Ahora, la definición exacta de este operador de conversión ha cambiado entre las versiones C ++ 03 y C ++ 11 del estándar. En versiones anteriores, era operator void*() const;(típicamente implementado como return fail() ? NULL : this;), mientras que en las más nuevas es explicit operator bool() const;(típicamente implementado simplemente como return !fail();). Ambas declaraciones funcionan bien en un contexto booleano, pero se comportan de manera diferente cuando (mal) se usan fuera de dicho contexto.
En particular, bajo las reglas de C ++ 03, cout << coutse interpretaría como cout << cout.operator void*()e imprimiría alguna dirección. Según las reglas de C ++ 11, cout << coutno debe compilarse en absoluto, ya que el operador está declarado explicity, por lo tanto, no puede participar en conversiones implícitas. De hecho, esa fue la principal motivación para el cambio: evitar que se compilara código sin sentido. Un compilador que cumpla con cualquiera de los estándares no produciría un programa que imprima "1".
Aparentemente, ciertas implementaciones de C ++ permiten mezclar y combinar el compilador y la biblioteca de tal manera que produzca un resultado no conforme (citando @StephanLechner: "Encontré una configuración en xcode que produce 1, y otra configuración que produce una dirección: Dialecto del idioma c ++ 98 combinado con "Biblioteca estándar libc ++ (biblioteca estándar LLVM con soporte para c ++ 11)" produce 1, mientras que c ++ 98 combinado con libstdc (biblioteca estándar gnu c ++) produce una dirección; "). Puede tener un compilador de estilo C ++ 03 que no entienda los explicitoperadores de conversión (que son nuevos en C ++ 11) combinados con una biblioteca de estilo C ++ 11 que define la conversión como operator bool(). Con tal mezcla, es posible cout << coutque se interprete como cout << cout.operator bool(), lo que a su vez es simple cout << truee imprime "1".
;al final de la primera línea de salida, no<<. No está imprimiendo lo que cree que está imprimiendo. Lo estás haciendocout << cout, que imprime1(usacout.operator bool(), creo). Luego5(de2+3) sigue inmediatamente, haciéndolo parecer el número quince.