r...@zedat.fu-berlin.de (Stefan Ram) writes:
> int main()
> { double x; bool ok; do
> { if( ::std::cin >> x ) ...
>
> . It compiles fine.
[...]
> int main()
> { double x; bool ok; do
> { if( ok = ::std::cin >> x )...
>
> error: cannot convert
> 'std::basic_istream<char>::__istream_type {aka
> std::basic_istream<char>}' to 'bool' in assignment
"if ( bool ok = ... )" compiles fine.
"if ( ok = bool(...) )" compiles fine.
Before C++11 there was no operator bool() (it was operator void*())
Since C++11 it is "explicit operator bool()"
Regarding conditions for if statements, (N4296, 6.4§3) says:
"The value of a condition that is an initialized declaration in a
statement other than a switch statement is the value of the declared
variable contextually converted to bool (Clause 4). [...] The value of a
condition that is an expression is the value of the expression,
contextually converted to bool for statements other than switch [...]"
Then, (6.4§5) says: "If a condition can be syntactically resolved as
either an expression or the declaration of a block-scope name, it is
interpreted as a declaration."
So "if ( bool ok = cin>>x )" (an initialized declaration) and
"if ( cin>>x )" (an expression, interpreted as a declaration) are
treated the same, and both match the requirements of an explicit
constructor. (I would call the latter an "implicitly explicit
construction" :-)
In contrast, "if ( ok = cin>>x )" tries to do two things:
1) evaluate cin>>x (returning an istream&)
2) assign to a bool
The assignment fails, because it requires a conversion that is not
explicit. Making it explicit (ok = bool(cin>>x)) solves the problem, as
noted above. There is no need for an "if" statement to exhibit the
problem:
ok = cin>>x;
fails to compile as well.
My conclusion is that the explicit qualifier on "istream::operator bool()"
is the cause of the error.
Does that sound plausible? Thanks for the example.
-- Alain.