4

I stumbled across this code.

    std::ostringstream str;
    /// (some usage)
    assert( ! str );

What does ostringstream signify when used in a bool context?

Is this possibly an incorrect usage that happens to compile and run?

Drew Dormann
  • 59,987
  • 13
  • 123
  • 180

3 Answers3

11

It tells you if the stream is currently valid. This is something that all streams can do. A file stream, for example, can be invalid if the file was not opened properly.

As a side note, this functionality (testing a stream as a bool) is achieved by overloading explicit operator bool in C++11 and later and by overloading the void* cast operator in versions before C++11.

Here is a link containing some examples of why a stream might fail. This isn't specific to string streams, but it does apply to them.

Edit: changed bool to void* after Martin York pointed out my mistake.

Drew Dormann
  • 59,987
  • 13
  • 123
  • 180
Naaff
  • 9,213
  • 3
  • 38
  • 43
  • 4
    Actually this is achieved by overloading the void* cast operator. IF the bool cast operator was used then the stream could be used in an arithmetic context and the compiler would cast to bool and use the value 0/1. a void* on the other hand can not be used in an arithmetic context but can be used in a bool context as NULL pointers evaluated to false. But in this case the operator ! is used to explicitly return a bool value. – Martin York May 07 '09 at 16:26
  • What would that signify specifically for an ostringstream? Out of memory, perhaps? – Drew Dormann May 07 '09 at 16:56
  • @Shmoopty: Same as for other streams. Attempt to read an integer from characters will set some error bit. Check out http://www.cplusplus.com/reference/iostream/ios/fail/ – Martin York May 07 '09 at 17:07
  • @Martin York: I see how that could happen with an istream. How can an ostringstream attempt to read an integer from characters as you describe? – Drew Dormann May 07 '09 at 21:17
  • 1
    @Shmoopty: I'm not sure how and ostringstream could fail. Running out of memory might do it, but I'm willing to bet that full memory just results in an exception rather than setting fail. What is clear is that ostringstream inherits from ios_base just like any std stream class, so it inherits the state flags as well, even if there is not as much call for them as there is in a class like ofstream or istringstream. – Naaff May 07 '09 at 22:08
  • @Martin: actually people overload an `operator mfptr` where `mfptr` is a member function pointer type, so that people don't try to eg. compare objects (which would compare void pointers). – Alexandre C. Apr 17 '11 at 17:49
  • 1
    @Alexandre C: Yes this is the newer technique. But the STL was built before this technique was (discovered/introduced) and as such it uses the void* trick. The newer method pointer trick is nicer becasue it reduces risks in auto conversion. – Martin York Apr 17 '11 at 20:58
4

For reference: ostringstream::operator void*() and ostringstream::operator!().

Donotalo
  • 12,748
  • 25
  • 83
  • 121
1

The expression is valid and evaluates the state of the stream. This feature is more commonly used on input streams:

istringstream is;
is.str( "foo" );
int x;
is >> x;

if ( ! is ) {
   cerr << "Conversion failed";
}

I'm not sure how any of the standard streaming functions could cause an ostringstream to go bad, but you could certainly write one yourself.