This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++11 status.

### 788. Ambiguity in [istream.iterator]

Section: 23.6.2 [istream.iterator] Status: C++11 Submitter: Martin Sebor Opened: 2008-02-06 Last modified: 2016-01-28

Priority: Not Prioritized

View all other issues in [istream.iterator].

View all issues with C++11 status.

Discussion:

Addresses UK 287

> It is not clear what the initial state of an `istream_iterator` should be. Is _value_ initialized by reading the stream, or default/value initialized? If it is initialized by reading the stream, what happens if the initialization is deferred until first dereference, when ideally the iterator value should have been that of an end-of-stream iterator which is not safely dereferencable?

> Recommendation: Specify _value_ is initialized by reading the stream, or the iterator takes on the end-of-stream value if the stream is empty.

The description of how an istream_iterator object becomes an end-of-stream iterator is a) ambiguous and b) out of date WRT issue 468:

> `istream_iterator` reads (using `operator>>`) successive elements from the input stream for which it was constructed. After it is constructed, and every time `++` is used, the iterator reads and stores a value of `T`. If the end of stream is reached (`operator void*()` on the stream returns `false`), the iterator becomes equal to the end-of-stream iterator value. The constructor with no arguments `istream_iterator()` always constructs an end of stream input iterator object, which is the only legitimate iterator to be used for the end condition. The result of `operator*` on an end of stream is not defined. For any other iterator value a `const T&` is returned. The result of `operator->` on an end of stream is not defined. For any other iterator value a `const T*` is returned. It is impossible to store things into istream iterators. The main peculiarity of the istream iterators is the fact that `++` operators are not equality preserving, that is, `i == j` does not guarantee at all that `++i == ++j`. Every time `++` is used a new value is read.

`istream::operator void*()` returns null if `istream::fail()` is `true`, otherwise non-null. `istream::fail()` returns `true` if `failbit` or `badbit` is set in `rdstate()`. Reaching the end of stream doesn't necessarily imply that `failbit` or `badbit` is set (e.g., after extracting an `int` from `stringstream("123")` the stream object will have reached the end of stream but `fail()` is `false` and `operator void*()` will return a non-null value).

Also I would prefer to be explicit about calling `fail()` here (there is no `operator void*()` anymore.)

[ Summit: ]

> Moved from Ready to Open for the purposes of using this issue to address NB UK 287. Martin to handle.

[ 2009-07 Frankfurt: ]

> This improves the wording.

> Move to Ready.

Proposed resolution:

Change 23.6.2 [istream.iterator]/1:

> `istream_iterator` reads (using `operator>>`) successive elements from the input stream for which it was constructed. After it is constructed, and every time `++` is used, the iterator reads and stores a value of `T`. If the end of stream is reached the iterator fails to read and store a value of `T` (`operator void*() fail()` on the stream returns `false true`), the iterator becomes equal to the end-of-stream iterator value. The constructor with no arguments `istream_iterator()` always constructs an end of stream input iterator object, which is the only legitimate iterator to be used for the end condition. The result of `operator*` on an end of stream is not defined. For any other iterator value a `const T&` is returned. The result of `operator->` on an end of stream is not defined. For any other iterator value a `const T*` is returned. It is impossible to store things into istream iterators. The main peculiarity of the istream iterators is the fact that `++` operators are not equality preserving, that is, `i == j` does not guarantee at all that `++i == ++j`. Every time `++` is used a new value is read.