58

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

なぜですか

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

に相当

cin >> x;
if (cin){}

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

4

9 に答える 9

72

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

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

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

if(cin>>x)

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

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

于 2011-07-22T14:31:37.993 に答える
39

注: C++98/03 と C++11 (およびそれ以降) の両方に対処するために、事実から 4 年後に回答が更新されました。


std::cinのインスタンスですstd::istream。そのクラスは、この質問に関連する 2 つのオーバーロードを提供します。

  • operator >>可能であれば、ストリームからターゲット変数にデータを読み取ります。ストリームの直接の内容をターゲット変数の型に変換できない場合、ストリームは代わりに無効としてマークされ、ターゲット変数はそのまま残ります。操作の成功/失敗に関係なく、戻り値はストリームへの参照です。
  • ストリーム参照をポインターにoperator void*()変換する (pre-C++11)、またはストリーム参照をブール値に変換する (C++11) のいずれかです。この変換の結果は、ストリームが有効な場合は非 null ポインター (C++11 より前) または (C++11) になりますが、null ポインター (C++11 より前) または(C++11 ) ) ストリームが有効でない場合。void*explicit operator bool()truefalse

ステートメントには、テストするif量としてブール値、整数、またはポインターが必要です。の結果は、上記のいずれでもないstd::cin >> xへの参照です。istreamただし、クラスには、参照をステートメントで使用可能なものistreamに変換するために使用できる変換演算子があります。これは、言語がテストに使用するバージョン固有の変換演算子です。読み取りに失敗するとストリームが無効とマークされるため、読み取りが機能しない場合、テストは失敗します。istreamififif

C++11 より前のより複雑な変換メンバーの理由は、operator void*C++11 まで既存のexplicitキーワードが変換演算子とコンストラクターに適用されるように拡張されていなかったためです。明示的operator bool()でない場合、プログラマーが自分自身を撃つ機会が多すぎます。などの問題もありoperator void*()ます。「安全な bool イディオム」で修正できたはずですが、単純に拡張するだけexplicitで、多くの SFINAE マジックを使用することなく、安全な bool イディオムが達成することを正確に達成できました。

于 2011-07-22T14:55:24.493 に答える
7

cinistream関数ではなく、型の (グローバル) 変数です。

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

于 2011-07-22T14:32:02.710 に答える
7

cinstd名前空間の変数です。

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

于 2011-07-22T14:32:31.040 に答える
6

上記の回答は有益です。ここで、追加のコメントをします。

std::cinクラスのオブジェクトであり、Cの streamに対応する標準入力ストリーム(つまり、キーボード) をistream表します。 stdin

cin >> xは、最初に標準入力ストリームから int を読み取り、それを に割り当てますx。その後、 への自己参照を返しcinます。したがって、関数呼び出しの戻り値cin >> xはまだcinです。

if 条件の点から、if(cin)if(cin >> x)は似ています。標準IO ライブラリは、次のようなストリームの関数を定義します (実装によって異なります)。

explicit operator bool() const; // C++11

また

operator void*() const; //C++98, C++2003

この 2 つの宣言から、ストリーム型を直接または間接的に (明らかなピンターを介して) 型にキャストすることがわかりますvoid*boolbool

この 2 つの関数内では、いくつかの基本的なIO ストリームステータス (クラス フィールド) に依存して、false を返すか true を返すかを決定します (void*場合によっては、そうであるかどうかnullptr)。

cinは、 casting-to-bool関数istreamを継承するクラスのインスタンスです。だからうまくいく!

于 2013-06-21T10:29:58.273 に答える
1

1)cinのインスタンスです。 http://www.cplusplus.com/reference/iostream/cin/istreamを参照してください。

2) の>>演算子はistream 左オペランドを返します。この場合は です。 http://www.cplusplus.com/reference/istream/istream/operator%3E%3E/cinを参照してください。この演算子は、 から文字が抽出されなかった場合にオンに設定されます。これは、リーダーが終了したため、読み取る文字がもうない場合です。failbitcinEOF

3) 上記 2) の時点で、読み取り操作の後に条件が評価さif (cin >> x)れるとif (cin)、このリンクhttp://www.cplusplus.com/reference/ios/ios/operator_bool/を参照すると、このifブロックは以下を返します:

  • failbitまたはの少なくとも 1 つbadbitが設定されている場合は、null ポインター。それ以外の場合のその他の値 (C++98 標準の場合)。

  • これらのエラー フラグの少なくとも 1 つが設定されている場合、関数は false を返し、それ以外の場合は true を返します。(C++11 標準用)

于 2015-04-17T06:37:53.293 に答える
1

std::cinstd::istreamクラスのインスタンスです。

cin >> xcinオブジェクトの関数を呼び出すだけです。関数を直接呼び出すことができます:

cin.operator >>(x);

一度に複数の変数を読み取れるようにするために、operator >>関数は呼び出されたストリームへの参照を返します。あなたは呼び出すことができます:

cin >> x >> y;

または同等:

cin.operator >>(x).operator >>(y);

また:

std::istream& stream = cin.operator >>(x);
stream.operator >>(y);

パズルの最後の部分は、 にstd::istream 変換できることboolです。bool は を呼び出すことと同じ!fail()です。

したがって、次のコードでは:

int x;
std::istream& stream = std::cin.operator >>(x);
bool readOK = !stream.fail();
if (readOK)
{
  std::cout << x << "\n";
}

bool readOK = !stream.fail();だけに減らすことができますbool readOK = stream;

boolストリームの状態を保存するために別の を必要としないので、if (stream).

一時stream変数を削除すると、 が得られif (std::cin.operator >>(x))ます。

演算子を直接使用すると、元のコードに戻ります。

int x;
if (std::cin >> x)
{
  std::cout << x << "\n";
}
于 2020-02-07T08:37:05.523 に答える
0

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

于 2011-07-22T14:31:53.140 に答える