c++conversion-operator

Why can std::cin not be implicitly converted to bool?


In C++ Primer 5th Ed., Chapter 14 discusses conversion operators:

Under earlier versions of the standard, classes that wanted to define a conversion to bool faced a problem: Because bool is an arithmetic type, a class-type object that is converted to bool can be used in any context where an arithmetic type is expected.

Such conversions can happen in surprising ways. In particular, if istream had a conversion to bool, the following code would compile:

int i = 42;
cin << i; // this code would be legal if the conversion to bool were not explicit!

This program attempts to use the output operator on an input stream. There is no << defined for istream, so the code is almost surely in error. However, this code could use the bool conversion operator to convert cin to bool. The resulting bool value would then be promoted to int and used as the left-hand operand to the built-in version of the left-shift operator. The promoted bool value (either 1 or 0) would be shifted left 42 positions.

Input streams can be converted to bool values representing the internal status of the stream (success or failure). We used to do:

while(std::cin >> str)...

So why shouldn't this compile?

int x = 0;
std::cin << x;

If I use an explicit cast it works:

(bool)cin << 5; // works although bad

Solution

  • The operator bool is declared explicit, so it shouldn't be implicitly converted to a boolean:

    bool b = std::cin; // Error
    

    So you need to explicitly convert cin to a boolean for it to work:

    bool b {std::cin}; // OK, explicitly converting
    

    So when you try to call

    std::cin << 5;
    

    It won't compile because you're expecting an implicit conversion, while the class only allows explicit ones. Which is this works:

    bool(std::cin) << 5;
    

    Now, why does while(std::cin >> x) compile? The Standard guarantees an explicit conversion to bool in this situation. See the great post linked in the question comments about that.