Does a mutable input iterator increment the old iterator values?

Iterators that additionally satisfy the requirements of output iterators are called mutable iterators. Immutable iterators are called constant iterators. [24.2.1: 4]

This suggests that you can have a variable input iterator that satisfies the requirements of both input and output iterators.

After increasing the input iterator, copies of its old value should not be sought [24.2.3]. However, the standard does not say the same for output iterators; in fact, the operational semantics for postfix incrementation are given as { X tmp = r; ++r; return tmp; } { X tmp = r; ++r; return tmp; } { X tmp = r; ++r; return tmp; } , assuming that output iterators cannot invalidate (copies) of old iterator values.

So, can the increment of a volatile input-iterator invalidate old copies of the iterator?

If so, how would you support code like X a(r++); *a = t X a(r++); *a = t or X::reference p(*r++); p = t X::reference p(*r++); p = t with (for example) a proxy object?

If not, why does boost::iterator claim that it needs a proxy object? (Link is code, scroll down to read comments on struct writable_postfix_increment_proxy and postfix_increment_result ). That is, if you can return a (dereferenced) copy of the old iterator value, why do you need to wrap this copy in a proxy?

+8
c ++ iterator
source share
2 answers

Explanation, if found in the next section, [24.2.5] Forward iterators, where it is shown how they differ from input and output iterators:

Two dereferenced iterators a and b type X offer a multi-pass guarantee if:

- a == b means ++a == ++b and
- X - pointer type or expression (void)++X(a), *a equivalent to *a expression.

[Note: the requirement a == b implies ++a == ++b (which is not true for input and output iterators) and removing restrictions on the number of assignments via a mutable iterator (which applies to output iterators) allows the use of multi-pass unidirectional algorithms with advanced iterators . -end note]

Unfortunately, the standard has to be read as a whole, and the explanation is not always where you expect it to be.

+6
source share

The input and output iterators are mainly intended for one-way traversal: describe sequences in which each element can be visited only once.

Threads are a great example. If you are reading from stdin or a socket or writing to a file, then there is only the current position of the stream. All other iterators pointing to the same base sequence become invalid when you increment the iterator.

Iterators ahead allow a multi-pass traversal, an additional guarantee you need: they guarantee that you can copy the iterator, enlarge the original, and the copy will still point to the old position, so you can iterate from there.

+4
source share

All Articles