tags:

views:

53

answers:

3

Say I have overridden the >> operator for a class like below:

friend istream& operator>>(istream& in, MyObject& obj)
{
    ...
    if (in.fail())
        // What do I do here?  Should obj be returned unmodified?
    ...
}

and say that the input stream is in a fail state because the data there means that I cannot get a valid MyObject out of it. How should I leave the obj object?

+2  A: 

Ideally, you just need to manipulate the state bits when your operator>> can't read what it is supposed to be read. In other words, the user should check if the stream is in a valid state before using your object.

AraK
A: 

I would recommend leaving it unmodified and throwing an exception, since the client code violates an essential assumption. To leave the object unmodified even if the stream fails half-way, read the contents into a temporary MyObject, and swap them when complete.

Pontus Gagge
I would recommend not doing this - people don't normally expect stream operations to throw.
anon
@Neil: which highlights a rather odd inconsistency in the C++ libraries. I can sort of see the point in claiming that malformed input is something to be expected, but it still leaves us with having to interleave explicit error checking with our stream operations. Which is shy I'm always looking for ways to wrap them with more consistent (i.e. exception based) fault handling.
Pontus Gagge
@Pontus If you provided a "read" constructor (or something similar) I'd agree that throwing an exception is the best way to go - my point was that people don't expect op>>() specifically to throw.
anon
@Neil: which expectation is an oddity. I never fully understood the design rationale for that aspect of stream operations - my guess would be that exceptions were still somewhat controversial.
Pontus Gagge
@Pontus Yes, the iostream library actually predates exceptions.
anon
+2  A: 

The way that most code that performs stream I/O is written is:

MyObject obj;

if ( ! ( cin >> obj ) ) {
   // handle error
}

In other words, it is up to the user of operator >> to check that the operation worked, and the way to do that is to test the state of the stream, not the object. I'd also observe that except for low-level "value" objects like strings and integers, stream input via operator >> is not normally very useful because it requires that the object being read is default constructible, and most higher level objects are not.

anon