夏の間、C++を学習するために「Accelerated C++」を使用してきましたが、概念が正しく理解されていないようです。
なぜ
int x;
if (cin >> x){}
に相当
cin >> x;
if (cin){}
コードを見ると、cinを変数として使用しているように思えます。しかし、私はそれが機能だと思った。キーボードに入力する値がxであるのに、なぜcinをこのように使用できるのでしょうか?
cin
は、標準入力ストリームを表すクラス istream
のオブジェクトです。 cstdio
ストリームstdin
に対応します。ストリームの演算子>>
overloadは、同じストリームへの参照を返します。ストリーム自体は、変換演算子を介してブール条件でtrueまたはfalseに評価できます。
cin
は、フォーマットされたストリーム抽出を提供します。操作cin >> x;
「x」は、数値以外の値を入力すると失敗します。そう:
if(cin>>x)
数字ではなく文字を入力すると、false
を返します。
C++ I/Oを使用したヒントとコツ のこのWebサイトも役立ちます。
注:回答は、C++ 98/03とC++ 11(およびそれ以降)の両方に対処するため、事実の4年後に更新されました。
_std::cin
_は_std::istream
_のインスタンスです。そのクラスは、この質問に関連する2つのオーバーロードを提供します。
operator >>
_は、可能であれば、ストリームからデータをターゲット変数に読み取ります。ストリームの直接の内容をターゲット変数の型に変換できない場合、代わりにストリームは無効としてマークされ、ターゲット変数は変更されません。操作の成功/失敗に関係なく、戻り値はストリームへの参照です。void*
_ポインターに変換するoperator void*()
(C++ 11以前)、またはストリームを変換するexplicit operator bool()
(C++ 11)ブールへの参照。この変換の結果は、非NULLポインター(C++ 11以前)またはストリームが有効な場合はtrue
(C++ 11)ですが、NULLポインター(C++ 11以前)ストリームが有効でない場合はfalse
(C++ 11)。if
ステートメントには、テストする数量としてブール、整数、またはポインターのいずれかが必要です。 _std::cin >> x
_の結果は、上記のいずれでもないistream
への参照です。ただし、クラスistream
には、istream
参照をif
ステートメントで使用可能なものに変換するために使用できる変換演算子があります。言語がif
テストに使用するのは、バージョン固有の変換演算子です。読み取りに失敗するとストリームに無効のマークが付けられるため、読み取りが機能しなかった場合、if
テストは失敗します。
C++ 11より前のより複雑な_operator void*
_変換メンバーの理由は、既存のexplicit
キーワードが変換演算子にも適用されるように拡張されたのはC++ 11までではなかったためです。コンストラクターとして。明示的ではないoperator bool()
は、プログラマーが足を踏み入れる機会が多すぎます。 operator void*()
にも問題があります。 「セーフブールイディオム」は修正されたはずですが、explicit
を拡張するだけで、セーフブールイディオムが達成することを正確に達成し、多くのSFINAEマジックを使用する必要はありませんでした。
cin
はistream
型の(グローバル)変数であり、関数ではありません。
istream
クラスは>>
演算子をオーバーライドして、入力を実行し、呼び出したオブジェクトへの参照を返します(cin
)。
cin
は、std
名前空間の変数です。
operator>>
はcin
への参照を返します。そのため、次のように記述できます:cin >> a >> b
、 の代わりに cin >> a; cin >> b;
上記の答えは参考になります。ここで追加のコメントをします。
_std::cin
_はクラスistream
のオブジェクトであり、Cのstdin
に対応する標準入力ストリーム(つまりキーボード)を表しますstream。
_cin >> x
_は、まず標準入力ストリームからintを読み取り、x
に割り当てます。その後、cin
への自己参照を返します。したがって、関数呼び出し_cin >> x
_の戻り値は、まだcin
です。
if conditionの点から、if(cin)
とif(cin >> x)
は互いに似ています。標準IOライブラリは、このようなストリームの関数を定義します(実装に依存します):
_explicit operator bool() const; // C++11
_
または
_operator void*() const; //C++98, C++2003
_
この2つの宣言から、cast thestream type直接または間接的に(_void*
_ pinter to bool
を介して)これは、bool
型に明らかです。
この2つの関数内では、いくつかの基本的なIO Steamstatuses(class fields)に依存して、falseを返すかtrueを返すかを決定します(_void*
_の場合) 、nullptr
であるかどうか)。
cin
は、casting-to-bool関数を継承するクラスistream
のインスタンスです。動作します!
式の結果
cin >> x
に評価する
cin
ストリームが読み取られた後。
私が知っているように、オーバーロードされた演算子>>はクラスistreamのオブジェクトを返します。ここに違いがない理由があります
1)cin
はistream
のインスタンスです。 http://www.cplusplus.com/reference/iostream/cin/ を参照してください。
2)istream
の_>>
_演算子は左オペランドを返します。この場合はcin
です。 http://www.cplusplus.com/referenceを参照してください/ istream/istream/operator%3E%3E / 。この演算子は、failbit
から文字が抽出されなかった場合、リーダーがcin
を終了した場合に、読み取る文字がなくなるため、EOF
をオンに設定します。
3)上記2)のように、読み取り操作後に条件が評価される場合、if (cin >> x)
はif (cin)
のようになります。このリンクを参照してください http:// www .cplusplus.com/reference/ios/ios/operator_bool / ご覧のとおり、このif
ブロックは以下を返します。
failbit
またはbadbit
の少なくとも1つが設定されている場合は、nullポインター。その他の値(C++ 98標準の場合)。
これらのエラーフラグの少なくとも1つが設定されている場合、関数はfalseを返し、そうでない場合はtrueを返します。 (C++ 11標準の場合)
cinはクラスのオブジェクトであるため、 http://www.cplusplus.com/reference/iostream/cin/ で詳細をご覧ください。