4

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
Boann
  • 48,794
  • 16
  • 117
  • 146
Maestro
  • 2,512
  • 9
  • 24
  • 3
    Does this answer your question? https://stackoverflow.com/questions/39995573/when-can-i-use-explicit-operator-bool-without-a-cast – 463035818_is_not_an_ai May 05 '20 at 22:03
  • 1
    your line of reasoning is almost correct. The only detail you miss is that `if (std::cin >> x)` is allowed even though the conversion is declared as explicit as explained in the Q&A I linked above – 463035818_is_not_an_ai May 05 '20 at 22:05
  • This is why in the early days the conversion was not too bool. It was to a type that could be interrupted in a bool context (not exact words). As a result we used to return pointers to member functions. These could be null or a pointer and when placed in a bool context with true or false. i.e. like `while (cin >> val)` would return a stream that would then result in a conversion to a pointer like object which is an integer type so can be use to force the loop to exit. The old days were fun. – Martin York May 05 '20 at 22:32

1 Answers1

5

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.

Joel Filho
  • 1,300
  • 1
  • 5
  • 7