[解決済み] なぜcoutは "2 + 3 = 15 "と表示するのですか?
質問
以下のプログラムの出力はなぜこのようなものになっているのでしょうか?
#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"
.
関連
-
[解決済み】C++でint型に無限大を設定する
-
[解決済み] error: 'ostream' does not name a type.
-
[解決済み】C++コンパイルタイムエラー:数値定数の前に期待される識別子
-
[解決済み】「corrupted size vs. prev_size」glibc エラーを理解する。
-
[解決済み] 既に.objで定義されている-二重包含はない
-
[解決済み】クラステンプレートの使用にはテンプレート引数リストが必要です
-
[解決済み】警告 - 符号付き整数式と符号なし整数式の比較
-
[解決済み】エラー。引数リストに一致するコンストラクタのインスタンスがない
-
[解決済み] 0.1fを0にすると、なぜ10倍もパフォーマンスが落ちるのですか?
-
[解決済み] Collatz予想の検証を行うC++のコードは、なぜ手書きのアセンブリよりも高速に動作するのでしょうか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】getline()が何らかの入力の後に使用されると動作しない 【重複あり
-
[解決済み】致命的なエラー LNK1169: ゲームプログラミングで1つ以上の多重定義されたシンボルが発見された
-
[解決済み】cc1plus:エラー:g++で認識されないコマンドラインオプション"-std=c++11"
-
[解決済み】「std::operator」で「operator<<」にマッチするものがない。
-
[解決済み】Visual C++で "Debug Assertion failed "の原因となる行を見つける。
-
[解決済み】オブジェクト引数のない非静的メンバ関数の呼び出し コンパイラーエラー
-
[解決済み】ファイルから整数を読み込んで配列に格納する C++ 【クローズド
-
[解決済み】浮動小数点数の乱数生成
-
[解決済み】クラスのコンストラクタへの未定義参照、.cppファイルの修正も含む
-
[解決済み] to_string は std のメンバーではない、と g++ が言っている (mingw)