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 of
r
are 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, r
need 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
(from X a(r++);
) cannot be used like *a = 0
:
"After this operation [i.e.,
++r
]r
is not required to be incrementable and any copies of the previous value ofr
are no longer required to be dereferenceable or incrementable."
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 the ostream_iterator
to actually increment.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With