Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

What is '!cin'?

63 views
Skip to first unread message

fl

unread,
Oct 31, 2015, 10:14:20 AM10/31/15
to
Hi,

I know cin is standard input. I see the following code, but I don't know when
the return value of cin is '0'.

Could you tell me that?

Thanks,




bool get_word(string &s1)
{
cout << "enter a word to search for, or q to quit: ";
cin >> s1;
if (!cin || s1 == "q") return false;
else return true;
}

Richard Damon

unread,
Oct 31, 2015, 10:54:52 AM10/31/15
to
cin is a istream.

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)

Alf P. Steinbach

unread,
Nov 1, 2015, 2:35:28 AM11/1/15
to
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. In C++98 this was an implicitly
invokable conversion to "void*". In C++11 and later it's an "explicit"
conversion to "bool", with special rules that allow such a conversion to
be implicitly invoked in a context requiring a "bool".

C++14 §4/4
«Certain language constructs require that an expression be converted to
a Boolean value. An expression e appearing in such a context is said to
be /contextually converted/ to bool and is well-formed if and only if
the declaration bool t(e); is well-formed, for some invented temporary
variable t (8.5).»

Essentially, writing "!stream" is equivalent to writing "stream.fail()".

Worth noting, that "stream.good()" is not the opposite of
"stream.fail()", and that the conversion to boolean is based on "fail()".


Cheers,

- Alf

fl

unread,
Nov 1, 2015, 2:00:06 PM11/1/15
to
Great thanks. I use MSVC 2010. What version is it, C++11, or C++14?
How can I know that?

fl

unread,
Nov 1, 2015, 2:03:08 PM11/1/15
to
On Sunday, November 1, 2015 at 2:35:28 AM UTC-5, Alf P. Steinbach wrote:
I am a little confused about the description. "!stream" is an explicit type
or an implicit type?


Thanks,

Paavo Helde

unread,
Nov 1, 2015, 3:46:34 PM11/1/15
to
fl <rxj...@gmail.com> wrote in
news:02748094-1a01-45fb...@googlegroups.com:
>
> Great thanks. I use MSVC 2010. What version is it, C++11, or C++14?
> How can I know that?

http://en.cppreference.com/w/cpp/compiler_support

In this table, MSVC2010 appears as MSVC 10.x (see
https://en.wikipedia.org/wiki/Visual_C%2B%2B). It does indeed contain some
C++11 features, but not the "Explicit conversion operators" feature
discussed in this thread.

hth
Paavo

Richard

unread,
Nov 1, 2015, 8:27:27 PM11/1/15
to
[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)

--
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
The Computer Graphics Museum <http://computergraphicsmuseum.org>
The Terminals Wiki <http://terminals.classiccmp.org>
Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>

Richard

unread,
Nov 1, 2015, 8:28:09 PM11/1/15
to
[Please do not mail me a copy of your followup]

Paavo Helde <myfir...@osa.pri.ee> spake the secret code
<XnsA545E79D77A7Bm...@216.166.105.131> thusly:
basic_ios::operator! is not a C++11/14/1z feature.

Alf P. Steinbach

unread,
Nov 2, 2015, 2:09:04 AM11/2/15
to
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

Richard Damon

unread,
Nov 2, 2015, 8:17:05 AM11/2/15
to
On 11/2/15 2:08 AM, Alf P. Steinbach wrote:
> On 11/2/2015 2:27 AM, Richard wrote:
>>
>> 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.
>

My guess is it is historical. I seem to remember a lot of debate about
adding something like operator bool() to classes as it opens up a lot of
unexpected side effects (since bool converts to so many different
things). Note that before C++11, it was operator void*() to avoid many
of the issues, and in C++11 in became explicit operator bool(), as
explicit was added to handle a number of the issues with a implicit
conversion operators in C++ code.

operator!(), largely because it is explicit doesn't have so many issues
so was added first as a quick way to test the stream.

0 new messages