1. ホーム
  2. c++

[解決済み] なぜcoutは "2 + 3 = 15 "と表示するのですか?

2022-07-28 01:17:53

質問

以下のプログラムの出力はなぜこのようなものになっているのでしょうか?

#include <iostream>
using namespace std;

int main(){

    cout << "2+3 = " <<
    cout << 2 + 3 << endl;
}

プロデュース

2+3 = 15

の代わりに、期待される

2+3 = 5


この質問はすでに何度もクローズ/リプレインされています。

終了に投票する前に、以下を検討してください。 このメタな議論 を検討してください。

どのように解決するのですか?

意図的であろうと、偶然であろうと、あなたは << を出力行の最後に書いていますが、これはおそらく ; . つまり、本質的には

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: "I found a setting in xcode thatduces 1, and another setting that yduces an address.引用: xcode で 1 を生成する設定とアドレスを生成する設定を見つけました。言語方言 c++98 と "標準ライブラリ libc++ (c++11 をサポートする LLVM 標準ライブラリ) " を組み合わせると 1 が得られ、一方 c++98 と libstdc (gnu c++ 標準ライブラリ) を組み合わせるとアドレスが得られ、 ") となります。C++03スタイルのコンパイラで explicit 変換演算子 (C++11 の新機能) を理解しない C++03 スタイルのコンパイラと、変換を次のように定義する C++11 スタイルのライブラリが組み合わされます。 operator bool() . このような組み合わせにより cout << cout として解釈されるようになります。 cout << cout.operator bool() と解釈されますが,これは単に cout << true と表示され "1" .