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

### 1311. multi-pass property of Forward Iterator underspecified

Section: 23.3.5.5 [forward.iterators] Status: Resolved Submitter: Alisdair Meredith Opened: 2010-02-07 Last modified: 2016-01-28

Priority: Not Prioritized

View all other issues in [forward.iterators].

View all issues with Resolved status.

Discussion:

The following example demonstrates code that would meet the guarantees of a Forward Iterator, but only permits a single traversal of the underlying sequence:

>     template< typename ForwardIterator>
>     struct bad_iterator {
>       shared_ptr<ForwardIterator> impl;

>       bad_iterator( ForwardIterator iter ) {
>          : impl{new ForwardIterator{iter} }
>          {
>       }

>       auto operator*() const -> decltype(*ForwardIterator{}) {
>          return **impl;
>       }

>       auto operator->() const -> ForwardIterator {
>          return *impl;
>       }

>       auto operator==(bad_iterator const & rhs) const -> bool {
>          return impl == rhs.impl;
>       }

>       auto operator++() -> bad_iterator& {
>          ++(*impl);
>          return *this;
>       }
>       // other operations as necessary...
>     };

Here, we use `shared_ptr` to wrap a forward iterator, so all iterators constructed from the same original iterator share the same 'value', and incrementing any one copy increments all others.

There is a missing guarantee, expressed by the following code sequence

>     FwdIter x = seq.begin();  // obtain forward iterator from a sequence
>     FwdIter y = x;            // copy the iterator
>     assert(x == y);           // iterators must be the same
>     ++x;                      // increment *just one* iterator
>     assert(x != y);           // iterators *must now be different*
>     ++y;                      // increment the other iterator
>     assert(x == y);           // now the iterators must be the same again

That inequality in the middle is an essential guarantee. Note that this list is simplified, as each assertion should also note that they refer to exactly the same element `(&*x == &*y)` but I am not complicating the issue with tests to support proxy iterators, or value types overloading unary `operator+`.

I have not yet found a perverse example that can meet this additional constraint, and not meet the multi-pass expectations of a Forward Iterator without also violating other Forward Iterator requirements.

Note that I do not yet have standard-ready wording to resolve the problem, as saying this neatly and succinctly in 'standardese' is more difficult.

[ 2010 Pittsburgh: Moved to NAD Editorial Resolved. Rationale added below. ]

Rationale:

Solved by N3066.

Proposed resolution: