On 11/2/2015 2:27 AM, Richard wrote:
> [Please do not mail me a copy of your followup]
>
> "Alf P. Steinbach" <
alf.p.stein...@gmail.com> spake the secret code
> <n14f76$tk2$
1...@dont-email.me> thusly:
>
>> On 10/31/2015 3:54 PM, Richard Damon wrote:
>>>
>> [snip]
>>> istreams define a member operator!() which is the equivalent to calling
>>> fail() to see if something has gone wrong with the stream (like it
>>> couldn't extract a string s1)
>>
>> Roughly, but the details are a bit different.
>>
>> C++ streams define conversion to boolean, and applying the built-in "!"
>> operator invokes that conversion.
>
> That's what I thought too, but this isn't the case:
>
> istream derives from basic_istream which derives from basic_ios, which
> has operator!:
> <
http://en.cppreference.com/w/cpp/io/basic_ios/operator!>
>
> The implicit conversion to bool happens when you do
>
> if (cin)
Oh, thanks :). I didn't know, and never suspected. I can't make sense of
it, it seems totally superfluous, e.g.
#include <iostream>
using namespace std;
struct S
{
#ifdef USE_NOT
auto operator!() const
-> bool
{ cout << "operator!\n"; return true; }
#endif
explicit operator bool() const
{ cout << "operator bool\n"; return true; }
};
auto main() -> int
{
S o;
(void) !o;
}
compiles nicely with or without USE_NOT defined, but with different
effects...
Happily "ios_base::operator!" is defined as "fail()", consistent with
the "ios_base::operator bool" definition as "!fail()".
I just can't make sense of it, why it's there. :(
Maybe it just prevents client code from botching things with a custom
definition like
auto operator!( S const& ) { return true; }
But with that hypothesis there should also be overloads for operator&&
and operator||?
Cheers,
- Alf