Intencionalmente ou por acidente, você tem <<no final da primeira linha de saída, onde você provavelmente quis dizer ;. Então você essencialmente tem
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
Portanto, a questão se resume a isso: por que cout << cout;imprimir "1"?
Isso acaba sendo, talvez surpreendentemente, sutil. std::cout, por meio de sua classe base std::basic_ios, fornece um certo operador de conversão de tipo que deve ser usado no contexto booleano, como em
while (cout) { PrintSomething(cout); }
Este é um exemplo muito ruim, pois é difícil fazer com que a saída falhe - mas std::basic_iosna verdade é uma classe base para os fluxos de entrada e saída e, para entrada, faz muito mais sentido:
int value;
while (cin >> value) { DoSomethingWith(value); }
(sai do loop no final do fluxo ou quando os caracteres do fluxo não formam um número inteiro válido).
Agora, a definição exata desse operador de conversão mudou entre as versões C ++ 03 e C ++ 11 do padrão. Nas versões mais antigas, era operator void*() const;(normalmente implementado como return fail() ? NULL : this;), enquanto nas mais recentes era explicit operator bool() const;(normalmente implementado simplesmente como return !fail();). Ambas as declarações funcionam bem em um contexto booleano, mas se comportam de maneira diferente quando (mis) usadas fora desse contexto.
Em particular, sob as regras do C ++ 03, cout << coutseria interpretado como cout << cout.operator void*()e impresso algum endereço. Sob as regras do C ++ 11, cout << coutnão deve ser compilado, pois o operador é declarado explicite, portanto, não pode participar de conversões implícitas. Essa foi, de fato, a principal motivação para a mudança - impedindo a compilação de códigos sem sentido. Um compilador que esteja em conformidade com qualquer padrão não produzirá um programa que imprima "1".
Aparentemente, certas implementações em C ++ permitem misturar e combinar o compilador e a biblioteca de uma maneira que produza resultados não conformes (citando @StephanLechner: "Encontrei uma configuração no xcode que produz 1 e outra que gera um endereço: Language dialect c ++ 98 combinado com "Biblioteca padrão libc ++ (biblioteca padrão LLVM com suporte a c ++ 11)" gera 1, enquanto c ++ 98 combinado com libstdc (biblioteca padrão gnu c ++) gera um endereço; "). Você pode ter um compilador no estilo C ++ 03 que não entenda os explicitoperadores de conversão (novos no C ++ 11) combinados com uma biblioteca no estilo C ++ 11 que define a conversão como operator bool(). Com essa mistura, torna-se possível cout << coutinterpretar como cout << cout.operator bool(), que por sua vez é simples cout << truee imprime "1".
;- e - vírgula no final da primeira linha de saída, não<<. Você não está imprimindo o que pensa que está imprimindo. Você está fazendocout << cout, que imprime1(usacout.operator bool(), eu acho). Então5(de2+3) segue imediatamente, fazendo com que pareça o número quinze.