Baik disengaja atau tidak, Anda memiliki <<di akhir garis output pertama, di mana Anda mungkin dimaksudkan ;. Jadi pada dasarnya Anda memilikinya
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
Jadi pertanyaannya bermuara pada ini: mengapa cout << cout;cetak "1"?
Ini ternyata, mungkin mengejutkan, halus. std::cout, melalui kelas dasarnya std::basic_ios, menyediakan operator konversi tipe tertentu yang dimaksudkan untuk digunakan dalam konteks boolean, seperti pada
while (cout) { PrintSomething(cout); }
Ini adalah contoh yang sangat buruk, karena sulit untuk mendapatkan output gagal - tetapi std::basic_iossebenarnya adalah kelas dasar untuk input dan output stream, dan untuk input itu jauh lebih masuk akal:
int value;
while (cin >> value) { DoSomethingWith(value); }
(keluar dari loop di ujung aliran, atau ketika karakter aliran tidak membentuk bilangan bulat yang valid).
Sekarang, definisi pasti dari operator konversi ini telah berubah antara versi standar C ++ 03 dan C ++ 11. Di versi yang lebih lama, itu operator void*() const;(biasanya diimplementasikan sebagai return fail() ? NULL : this;), sedangkan di versi yang lebih baru explicit operator bool() const;(biasanya diimplementasikan sebagai return !fail();) Kedua deklarasi berfungsi dengan baik dalam konteks boolean, tetapi berperilaku berbeda ketika (mis) digunakan di luar konteks tersebut.
Secara khusus, di bawah aturan C ++ 03, cout << coutakan ditafsirkan sebagai cout << cout.operator void*()dan mencetak beberapa alamat. Di bawah aturan C ++ 11, cout << couttidak boleh dikompilasi sama sekali, karena operator dinyatakan explicitdan karenanya tidak dapat berpartisipasi dalam konversi tersirat. Itu sebenarnya adalah motivasi utama untuk perubahan - mencegah penyusunan kode yang tidak masuk akal. Kompiler yang sesuai dengan standar mana pun tidak akan menghasilkan program yang mencetak "1".
Rupanya, implementasi C ++ tertentu memungkinkan pencampuran dan pencocokan kompiler dan perpustakaan sedemikian rupa sehingga menghasilkan hasil yang tidak sesuai (mengutip @StephanLechner: "Saya menemukan pengaturan dalam xcode yang menghasilkan 1, dan pengaturan lain yang menghasilkan alamat: Dialek bahasa c ++ 98 dikombinasikan dengan "Perpustakaan standar libc ++ (perpustakaan standar LLVM dengan dukungan c ++ 11)" menghasilkan 1, sedangkan c ++ 98 dikombinasikan dengan libstdc (gnu c ++ perpustakaan standar) menghasilkan alamat; "). Anda dapat memiliki kompiler gaya C ++ 03 yang tidak memahami explicitoperator konversi (yang baru dalam C ++ 11) dikombinasikan dengan pustaka gaya C ++ 11 yang mendefinisikan konversi sebagai operator bool(). Dengan campuran seperti itu, menjadi mungkin untuk cout << coutdiartikan sebagai cout << cout.operator bool(), yang pada gilirannya sederhana cout << truedan dicetak "1".
;di akhir garis output pertama, bukan<<. Anda tidak mencetak apa yang menurut Anda dicetak. Anda lakukancout << cout, yang mencetak1(menggunakancout.operator bool(), saya pikir). Kemudian5(dari2+3) langsung mengikuti, membuatnya tampak seperti angka lima belas.