Why do cin and cout have conversion to a void* and not bool?

Both std::cin and std::cout provide a conversion to a void* type, but not to a boolean:

operator void* (); // zero if and only if fail()

What use does a conversion to a boolean have, and which pitfalls does the current implementation save us from?

First off, a conversion to a boolean type is useful for the following construct:

while (cin >> str)
    // ...

But why is it a conversion to a void* and not to a bool?

This is actually pretty clever. If there was a conversion to a bool type, the following lines would not generate a compile error:

int n = 3;
cin << n; // convert cin to bool, promote to int & shiftleft
cout >> n; // convert cout to bool, promote to int & shiftright

This is a pretty good example of a smart design by the STL folks.

7 thoughts on “Why do cin and cout have conversion to a void* and not bool?

  1. hey!
    It was very interesting!
    Thank’s for the info!
    (I love the way you’ve written, it was fascinating!)

  2. But in the std namespace there is an overload of the operator<<(ostream& os, int) why would the compiler choose to convert cin to bool rather then calling operator<<(..) with the given paramters?
    please answer this one.

    1. I am not sure if I understand your question, but

      There is nothing wrong with using

      cout << num


      cin >> num

      The problem at hand is that using

      cout >> num

      makes no sense, and we would like the compiler to generate an error in that case (since there’s no overload for operator>>(ostream&, int)).

      In your question you are making a reference to ostream and operator<<, but then you ask about cin (which is an istream, not an ostream). Since there’s no proper operator overload for that, a conversion should be attempted. Such a conversion should fail for the reasons listed above.

      Please let me know if you still have questions, I’ll be more than happy to help. Thanks for the interest.

      1. No question, you undertood me correctly, and actually I was mistaken about the signs and didn’t notice that you used the opposite sign( i mean >> instead of <<).
        It's ok now.
        You are pretty skilled c++ programmer, your blog is great and I love your posts please keep posting, may be you can talk about the next revision of c++? I have found cool things there in particular literal overloading is pretty nice and nifty.

        1. By the way, regarding the sophistication of the STL developers. there is also another thing I found interesting about STL is that there is a seperation between a pop operation and a front/back operation on a STL container, and why there isn’t such an operation frontAndPop for example? for me it sounds very convenient to use rather then first to use front and then pop. but actually there is a reason about it, it is because by seperating front and pop operation you actually can cope with cases where there is an exception, and make your code more exception safe(to continue to be in a consistent state), for example:

          int x = vec.back();
          //.. some code here..(may throw) if it throws you don't lose the vector's last element! 
          1. if you would use such an imaginary frontAndPop() operation then the following code will be exception-unsafe:

            string st(vec.frontAndPop()); // if frontAndPop() throws you lost your element(not consistent).

            if the copy construction of string fails then you lost the element you’ve just popped. if frontAndPop throws it’s still ok.

          2. I took the liberty to merge some of your replies, hope you don’t mind. Indeed, adding an EDIT button would be just wonderful.. Unfortunately, I am not sure if there’s such an option here (at least I was not able to find one).

            Much thought has been put in the STL, and there is much to be learned from its design, functionality, and implementation. The point you brought up is another valid example. Thanks.

Leave a Reply

Your email address will not be published. Required fields are marked *