Remember that your code is equivalent to:
while (std::cin.operator>>(value)) { }
Or:
while (1) {
std::cin >> value ;
if (!std::cin) break ;
}
The "code" always tries to read from std::cin
into value
before testing std::cin
.
Let's look at the quote:
[...] The input operator (§ 1.2, p. 8) returns its left operand, which in this case is std::cin. [...]
This only means that std::cin.operator>>(value)
return std::cin
.
This condition, therefore, tests std::cin. When we use an istream as a condition, the effect is to test the state of the stream. If the stream is valid—that is, if the stream hasn’t encountered an error—then the test succeeds.
What the text book says is that after trying to read an integer from std::cin
to value
, the >>
operator returns std::cin
. If std::cin
is in a good state after reading value
, then the test passes, otherwize it fails.
Some extra details:
When you do std::cin >> value
, you basically call istream::operator>>(int&)
, and yes there is a test inside that method: If the test passes, then the internal state of std::cin
is set to ios_base::goodbit
, if it fails, internal state is set to on of the error flag (eofbit
, failbit
or badbit
).
Depending on the exception mask
for std::cin
, if the internal test fails, an exception may be thrown.
From your quote:
When we use an istream as a condition, the effect is to test the state of the stream.
This basically mean that:
if (std::cin) { }
Is equivalent to:
if (!std::cin.fail()) { }
And std::cin.fail()
check for failbit
or badbit
. This means that while (std::cin >> value) { }
does not test the eofbit
flag and will only fail when the input cannot be converted to an integer value.