web-dev-qa-db-ja.com

if(cin >> x)-なぜその条件を使用できるのですか?

夏の間、C++を学習するために「Accelerated C++」を使用してきましたが、概念が正しく理解されていないようです。

なぜ

int x;
if (cin >> x){}

に相当

cin >> x;
if (cin){}

コードを見ると、cinを変数として使用しているように思えます。しかし、私はそれが機能だと思った。キーボードに入力する値がxであるのに、なぜcinをこのように使用できるのでしょうか?

47
Muhsin Ali

cinは、標準入力ストリームを表すクラス istream のオブジェクトです。 cstdioストリームstdinに対応します。ストリームの演算子>>overloadは、同じストリームへの参照を返します。ストリーム自体は、変換演算子を介してブール条件でtrueまたはfalseに評価できます。

cinは、フォーマットされたストリーム抽出を提供します。操作cin >> x;

「x」は、数値以外の値を入力すると失敗します。そう:

if(cin>>x)

数字ではなく文字を入力すると、falseを返します。

C++ I/Oを使用したヒントとコツ のこのWebサイトも役立ちます。

59
user195488

注:回答は、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マジックを使用する必要はありませんでした。

33
David Hammen

cinistream型の(グローバル)変数であり、関数ではありません。

istreamクラスは>>演算子をオーバーライドして、入力を実行し、呼び出したオブジェクトへの参照を返します(cin)。

7
SLaks

cinは、std名前空間の変数です。

operator>>cinへの参照を返します。そのため、次のように記述できます:cin >> a >> b、 の代わりに cin >> a; cin >> b;

6
Olympian

上記の答えは参考になります。ここで追加のコメントをします。

_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のインスタンスです。動作します!

4
Zachary

式の結果

cin >> x

に評価する

cin

ストリームが読み取られた後。

4
Erix

私が知っているように、オーバーロードされた演算子>>はクラスistreamのオブジェクトを返します。ここに違いがない理由があります

0
Vitaly Davydov

1)cinistreamのインスタンスです。 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標準の場合)

0
Ryan Le

cinはクラスのオブジェクトであるため、 http://www.cplusplus.com/reference/iostream/cin/ で詳細をご覧ください。

0
Emil Condrea