Que ce soit intentionnellement ou par accident, vous avez <<à la fin de la première ligne de sortie, où vous vouliez probablement dire ;. Donc, vous avez essentiellement
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
La question se résume donc à ceci: pourquoi cout << cout;imprimer "1"?
Cela s'avère, peut-être étonnamment, subtil. std::cout, via sa classe de base std::basic_ios, fournit un certain opérateur de conversion de type qui est destiné à être utilisé dans un contexte booléen, comme dans
while (cout) { PrintSomething(cout); }
C'est un exemple assez médiocre, car il est difficile de faire échouer la sortie - mais std::basic_iosc'est en fait une classe de base pour les flux d'entrée et de sortie, et pour l'entrée, cela a beaucoup plus de sens:
int value;
while (cin >> value) { DoSomethingWith(value); }
(sort de la boucle à la fin du flux, ou lorsque les caractères du flux ne forment pas un entier valide).
Désormais, la définition exacte de cet opérateur de conversion a changé entre les versions C ++ 03 et C ++ 11 de la norme. Dans les anciennes versions, il était operator void*() const;(généralement implémenté en tant que return fail() ? NULL : this;), tandis que dans les versions plus récentes, il était explicit operator bool() const;(généralement implémenté simplement en tant que return !fail();). Les deux déclarations fonctionnent correctement dans un contexte booléen, mais se comportent différemment lorsqu'elles sont (mal) utilisées en dehors de ce contexte.
En particulier, sous les règles C ++ 03, cout << coutserait interprété comme cout << cout.operator void*()et afficherait une adresse. Sous les règles de C ++ 11, cout << coutne doit pas du tout compiler, car l'opérateur est déclaré explicitet ne peut donc pas participer aux conversions implicites. C'était en fait la principale motivation du changement - empêcher la compilation de code absurde. Un compilateur conforme à l'une ou l'autre des normes ne produirait pas de programme qui imprime "1".
Apparemment, certaines implémentations C ++ permettent de mélanger et de faire correspondre le compilateur et la bibliothèque de manière à produire un résultat non conforme (citant @StephanLechner: "J'ai trouvé un paramètre dans xcode qui produit 1, et un autre paramètre qui donne une adresse: dialecte de langue c ++ 98 combiné avec "Bibliothèque standard libc ++ (bibliothèque standard LLVM avec support c ++ 11)" donne 1, alors que c ++ 98 combiné avec libstdc (bibliothèque standard gnu c ++) donne une adresse; "). Vous pouvez avoir un compilateur de style C ++ 03 qui ne comprend pas explicitles opérateurs de conversion (qui sont nouveaux dans C ++ 11) combiné avec une bibliothèque de style C ++ 11 qui définit la conversion comme operator bool(). Avec un tel mélange, il devient possible cout << coutd'être interprété comme cout << cout.operator bool(), qui à son tour est simplement cout << trueet imprime "1".
;à la fin de la première ligne de sortie, non<<. Vous n'imprimez pas ce que vous pensez imprimer. Vous faitescout << cout, ce qui imprime1(il utilisecout.operator bool(), je pense). Puis5(de2+3) suit immédiatement, faisant ressembler le nombre quinze.