Per the (excellent) question C++ OutputIterator post-increment requirements, we observe that for a dereferenceable and incrementable value r of OutputIterator type X, and value o of appropriate type, the expression
*r++ = o;
is valid and has equivalent semantics to
X a(r);
++r;
*a = o;
However, is it still the case the a is dereference-assignable if r has been incremented more than once in the intervening period; that is, is this code valid?
X a(r);
++r;
++r;
*a = o;
It’s difficult to see how operations on a value can have an effect on the validity of operations on another value, but e.g. InputIterator (24.2.3) has, under the postconditions of ++r:
Any copies of the
previous value ofrare no
longer required either to be
dereferenceable or to be in
the domain of==.
Relevant sections: 24.2.2 Iterator, 24.2.4 Output iterators, 17.6.3.1 Template argument requirements.
Also, if this is not required to be valid, are there any situations where exploiting its non-validity would aid in the implementation (w.r.t. efficiency, simplicity) of an OutputIterator type while still observing the existing requirements?
This issue was raised in 2004 as defect 485, and the wording in n3066 clarifies the issue, requiring that an output iterator need only support a sequence of alternating increments and dereference/assignments. So in your example,
rneed not be incrementable after the first++r, unless there is an intervening dereference/assignment. This behavior is also required by SGI’s STL (see footnote 3). As you mentioned above, n3225 appeared without the fixes from n3066, so defect 2035 was raised; but alas the fix did not make it into the published version of C++11 (ISO/IEC 14882:2011).Furthermore, defect 2035 says that
a(fromX a(r++);) cannot be used like*a = 0:There are situations where this may aid the implementation (in terms of simplicity): see e.g. this question on
ostream_iterator, where such (invalid) double increments are ignored simply returning*this; only a dereference/assignment causes theostream_iteratorto actually increment.