Que ce soit intentionnellement ou par accident, vous disposez d' <<
à la fin de la première sortie de ligne où vous avez probablement censé ;
. Donc, vous avez
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
Donc, la question se résume à ceci: pourquoi est - cout << cout;
imprimer "1"
?
Cela s'avère être peut-être étonnamment, subtile. std::cout
, par l'intermédiaire de sa classe de base std::basic_ios
, fournit un certain type d'opérateur de conversion qui est destiné à être utilisé dans le contexte booléen, comme dans
while (cout) { PrintSomething(cout); }
C'est un assez mauvais exemple, car il est difficile d'obtenir une sortie à l'échec - mais std::basic_ios
est en fait une classe de base pour les entrées et les flux de sortie et d'entrée, il fait beaucoup plus de sens:
int value;
while (cin >> value) { DoSomethingWith(value); }
(sort de la boucle à la fin du flux, ou lorsque les flux de caractères ne forment pas un entier valide).
Maintenant, la définition exacte de cette opérateur de conversion a changé entre le C++03 et C++11 versions de la norme. Dans les anciennes versions, il a été operator void*() const;
(généralement mis en œuvre en tant que return fail() ? NULL : this;
), tandis que dans les plus récents c'est explicit operator bool() const;
(généralement mis en œuvre simplement en tant que return !fail();
). Les deux déclarations du bon travail, dans un contexte booléen, mais se comportent différemment lorsqu' (sig)utilisé en dehors d'un tel contexte.
En particulier, sous C++03 règles, cout << cout
serait interprété comme cout << cout.operator void*()
et imprimer des adresses. En vertu de C++11, les règles, cout << cout
ne devrait pas compiler à tous, que l'opérateur est déclaré explicit
et ne peut donc pas participer à des conversions implicites. C'est en fait la principale motivation pour le changement de la prévention absurde de code à partir de la compilation. Un compilateur qui est conforme soit à la norme ne serait pas produire un programme qui imprime "1"
.
Apparemment, certains C++ implémentations permettent de mélanger et assortir le compilateur et de la bibliothèque, de telle manière que le produit non conforme résultats (en citant @StephanLechner: "j'ai trouvé un réglage dans xcode qui produit 1, et un autre paramètre qui donne une adresse: dialecte du Langage c++98 combinée avec la "bibliothèque Standard libc++ (LLVM de la bibliothèque standard du c++11)" les rendements de 1, alors que c++98 combiné avec libstdc (gnu c++ standard library) donne une adresse;"). Vous pouvez avoir un C++03-style compilateur de ne pas comprendre explicit
opérateurs de conversion (qui sont nouveaux dans C++11), combiné avec le C++11 bibliothèque de style qui définit la conversion, comme operator bool()
. Avec un tel mélange, il devient possible pour cout << cout
être interprétés en cout << cout.operator bool()
, qui à son tour est tout simplement cout << true
et imprime "1"
.