# Boost :

From: Douglas Gregor (gregod_at_[hidden])
Date: 2001-07-07 16:40:46

On Saturday 07 July 2001 02:55, you wrote:
> On Fri, 6 Jul 2001, Douglas Gregor wrote:
> > On Friday 06 July 2001 12:14, you wrote:
> > > Iterators
> > > are used in algorithms to iterate over (pseudo)sequences. For
> > > input iterators, increment must move the iterator and dereference
> > > must not. Dereferencing an input iterator twice must give the
> > > same element of the (pseudo)sequence. Whether that element has
> > > a stable value has nothing to do with the iterator.
> >
> > From which stated input iterator requirements (i.e., clause/table in
> > the C++ standard) do you conclude this?
>
> The increment must move the iterator has been demonstrated by the
> use of the distance algorithm on input iterator.
>
> Ok, I'll play the game. 24.1 Iterators are a generalization of
> pointers ...
>
> Dereferencing a pointer does not modify the pointer.
>
> Now compare table 72 to tables 73-76. Notice that the formats are
> different. Something funny happened on the way to the standard.
> Table 72 had a column removed. Is this the correct format and
> time did not permit changing the others? Are the others correct
> and this is an editorial error? Did the left hand not know what
> the right hand was doing?
>
> Look at tables 73 and 74. ++r ... &++r == &r. Table 75. --r ...
> &--r == &r. Table 72. ++r ... duh. Is t = *++r equivalent to
> ++r; t = *r for input iterators? Following b = ++a, is a == b?
>
> Look at table 74. *a ... a == b implies *a == *b. This is obviously
> not an implication that T must be equality comparable. Should it
> read a == b implies &*a == &*b? Or *a is equivalent to *b? Can
> you find anything in the standard which shows if a == b that after
> *a = t it is still true that a == b?
>
> Now table 72. a == b implies *a is equivalent to *b. You claim
> that this allows side effects which would make T is equality
> comparable and a == b implies *a == *b invalid. It can't be
> changed to a == b implies &*a == &*b because *r could return an
> rvalue. Even for istream_iterator which is buffered and *r returns
> a T const&, a == b would not imply that &*a == &*b. The standard
> neither requires nor prohibits this. Amusingly, it would be true that
> &*r == &*++r.

"Equivalent" is a perfectly good word if it were defined a little more
carefully :)

> So, there are lots of things in clause 24 which are less than clear.
>
> I think that your motivation for the subject iterator is the best
> example of why *r is stable. There are several algorithms which
> return input iterators and they are only useful when that is true.
> The STL is algorithms which work with iterators which have the
> desired properties. Maybe clause 24 is a mess, but the intent is
> clear.
>
> Finally, look at the first sentence of clause 24. This clause
> describes iterators over containers, streams, and stream buffers.
> If you have something which is not an iterator over one of them,
> this clause does not apply and it is not any kind of iterator.
> I can accept an iterator over a virtual container, but that implies
> a stable operator*. Looking at a (virtual) container does not
> change the container nor the iterator. Even output iterators have
> a stable operator* which does nothing observable.
>
> John

Output iterators are part of the confusion - the final note for output
iterators is that the result of dereferencing them is only suitable for the
left-hand side of an assignment, and that assignment through any given value
of an output iterator occurs only once. So output iterators aren't
necessarily stable. With clause 24 being vague on the stability of operator*
for input iterators, and a non-stable operator* for output iterators, IMHO
the intent wasn't clear.

Doug