>>演算子を使用すると、演算子の左側にあるオブジェクトが返されるというC++の本を読んでいるので、この例では
std::cin >> value1;
コードはstd::cin
を返します。
しかし、私がこれを行う場合
while(std::cin >> value1)
私のコードはstd::cin
エラーが発生するまでループになります。つまり、演算子はstd::cin
が失敗しない場合はtrue、std::cin
の場合はfalseを返すbool
を返す必要があります。 ] _失敗します。
どれですか?
[...]つまり、演算子がブール値を返すことを意味する必要があります[...]
いいえ、_std::cin
_(参照による)を返します。 while(std::cin >> value);
が機能する理由は、_std::istream
_(_std::cin
_のタイプ)に 変換演算子 。
変換演算子は基本的に、クラスを暗黙的に(explicit
とマークされていない場合)特定の型に変換することを許可します。この場合、_std::istream
_はその_operator bool
_を定義して、エラー(通常はfailbit
)が発生したかどうかを返します。
[std::ios_base::operator bool()]
ストリームにエラーがなく、I/O操作の準備ができている場合は、
true
を返します。具体的には、!fail()
を返します。
_explicit operator bool() const;
_
演算子がexplicit
(if (std::cin);
のような暗黙の変換を許可しない)であっても、bool
を必要とするコンテキストで使用される場合、修飾子は無視されることに注意してください。 if
、while
ループ、for
ループのように。ただし、これらは例外であり、規則ではありません。
次に例を示します。
_if (std::cin >> value); //OK, a 'std::istream' can be converted into a 'bool', which
//therefore happens implicitly, without the need to cast it:
if (static_cast<bool>(std::cin >> value)); //Unnecessary
bool b = std::cin >> value; //Error!! 'operator bool' is marked explicit (see above), so
//we have to call it explicitly:
bool b = static_cast<bool>(std::cin >> value); //OK, 'operator bool' is called explicitly
_
_std::istream
_(_std::cin
_がオブジェクトであるクラス)には、次のメンバー関数があります。
_explicit operator bool() const;
_
オブジェクトがエラー状態の場合はfalseを返し、それ以外の場合はtrueを返します。これが、while(std::cin >> value1)
コンストラクトが機能する理由です。 C++ 11より前は、代わりに次の非明示的な関数がありました。
_operator void*() const;
_
オブジェクトがエラー状態の場合、これはnullポインターを返し、同じ目的を果たします。
ストリームの操作はストリームへの参照を返します。
したがって、bool
ではありません。
これを行うことができるのと同じ理由で、結果をif
条件に貼り付けることができます。
_void* ptr = foo();
if (ptr) { /*...*/ }
_
そして、そのことについては、これは:
_int x = foo();
if (x) { /*...*/ }
_
ここでのptr
とx
はどちらも、条件で使用するためにbool
に変換できます。 _std::cin
_の場合、変換は、この正確なタスクのために明示的に(しゃれを意図して)追加された_std::ostream
_クラス内のoperator bool()
によって行われます。
_std::cin
_はタイプ_std::istream
_です(これは _std::basic_istream<char>
_ のtypedef
です)
異なるオーバーロードされた_operator>>
_ for _basic_istream
_ が表示された場合、それらはすべて_basic_istream
_への参照を返しています。したがって、ここでの_operator>>
_はbool
を返さず、代わりに「_std::cin
_」自体を返すことが1つ明確になります。 bool
値を返す_operator>>
_は表示されません。
では、問題は、_std::basic_istream
_をbool
にどのように変換するかということです。
答えは次のとおりです。変換演算子がこの目的で呼び出されています。
_std::basic_istream
_は親から operator bool()
を継承します_std::basic_ios
_
_explicit operator bool() const;
_
これにより、_std::basic_istream
_オブジェクトをbool
に変換できます。 explicit
とマークされているのは簡単に不思議に思うかもしれませんが( なぜexplicit
とマークされているのか を参照)、それでもbool
またはif
で暗黙的にwhile
に変換されます。
この質問への答えは、if
またはwhile
が「暗黙的に」明示的な変換を使用することです。 ( @R。MartinhoFernandesによるこの回答 を参照)。したがって、if
、while
、およびfor
は、この「contexual変換」からbool
への暗黙的な変換が行われる場所の1つです。