Будь то навмисно чи випадково, у вас є <<в кінці першого рядка вихід, де ви, мабуть, мали на увазі ;. Так ви по суті маєте
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
Тож питання зводиться до цього: чому cout << cout;друкується "1"?
Це виявляється, мабуть напрочуд, тонко. std::coutчерез базовий клас std::basic_iosзабезпечує оператор перетворення певного типу, який призначений для використання в булевому контексті, як у
while (cout) { PrintSomething(cout); }
Це досить бідний приклад, оскільки складно отримати вихід з ладу - але std::basic_iosнасправді базовий клас як для вхідних, так і вихідних потоків, а для введення має набагато більше сенсу:
int value;
while (cin >> value) { DoSomethingWith(value); }
(виходить з циклу в кінці потоку або коли символи потоку не утворюють дійсного цілого числа).
Тепер точне визначення цього оператора перетворення змінилося між C ++ 03 та C ++ 11 версіями стандарту. У старих версіях він був operator void*() const;(як правило, реалізований як return fail() ? NULL : this;), а в більш нових версіях - explicit operator bool() const;як правило, просто як return !fail();). Обидві декларації справно працюють у булевому контексті, але поводяться по-різному, коли (неправильно) використовуються поза таким контекстом.
Зокрема, відповідно до правил C ++ 03, cout << coutінтерпретуватимуться як cout << cout.operator void*()та надрукувати якусь адресу. Згідно з правилами C ++ 11, cout << coutвзагалі не слід збирати компіляцію, оскільки оператор декларується explicitі тому не може брати участь у неявних перетвореннях. Це насправді була основною мотивацією змін - запобігання безглуздого коду від компіляції. Компілятор, який відповідає будь-якому стандарту, не створював би програму, яка друкує "1".
Мабуть, певні реалізації C ++ дозволяють змішувати та узгоджувати компілятор та бібліотеку таким чином, що створює невідповідний результат (цитуючи @StephanLechner: "Я знайшов налаштування в xcode, який виробляє 1, та інше налаштування, яке дає адресу: Мова діалект c ++ 98 у поєднанні зі "Стандартною бібліотекою libc ++ (стандартна бібліотека LLVM з підтримкою c ++ 11)" дає 1, тоді як c ++ 98 у поєднанні з libstdc (gnu c ++ стандартна бібліотека) дає адресу; "). Ви можете мати компілятор стилю C ++ 03, який не розуміє explicitоператорів перетворення (які є новими в C ++ 11) у поєднанні з бібліотекою стилю C ++ 11, яка визначає конверсію як operator bool(). З такою сумішшю стає можливою cout << coutінтерпретація як cout << cout.operator bool(), що, в свою чергу, просто cout << trueі друкує "1".
;в кінці першого рядка виводу, а не<<. Ви не друкуєте те, що думаєте, що друкуєте. Ви робитеcout << cout, який друкує1(він використовуєcout.operator bool(), я думаю). Потім5(з2+3) негайно випливає, роблячи це схожим на число п’ятнадцять.