|
|
None of the examples so far has checked for errors. Omitting such checks would be bad style, except that the iostream library is arranged so that errors are propagated.
Streams have an error state. When an error occurs bits are set in the state according to the general category of the error. By convention, inserters ignore attempts to insert things into an ostream with error bits set, and such attempts do not change the stream's state. The error bits are declared in an enum, which is declared inside the declaration of class ios.
class ios { enum io_state { goodbit=0, eofbit=1, failbit=2, badbit=4 } ; } ;ios::goodbit is not really a ``bit.'' It is zero and indicates the absence of any bit.
In the definitions of the Pair and Vec inserters, if an error occurs some wasted computation may be done as the code does insertions that have no effect. But eventually the error will be properly propagated to the caller.
It is a good idea to check the output stream in some central place. For example:
if (!cout) error("aborting because of output error") ;The state of cout is examined with operator!, which will have a non-zero value if the state indicates an error has occurred. This and other examples in this document assume that error() is a function to be called when an error is discovered, and that it does not return. But error() is not part of the iostream library.
An ostream can also appear in a ``boolean'' position and be tested.
if ( cout << x ) return ; ... ; // error handlingThe magic here is that ios contains a definition for operator void* that returns a non-null value when the error state is non-zero.
An explicit member function also exists:
if ( ... , cout.good() ) return ; ... ; // error handlingThe reader is referred to the man pages for other member functions that examine the error state.