C++ Logo

std-discussion

Advanced search

Re: erase and iterator invalidation

From: Daniel Krügler <daniel.kruegler_at_[hidden]>
Date: Tue, 12 Dec 2023 10:44:19 +0100
Am Di., 12. Dez. 2023 um 09:11 Uhr schrieb Yongwei Wu <wuyongwei_at_[hidden]>:
>
> On Tue, 12 Dec 2023 at 14:14, Daniel Krügler <daniel.kruegler_at_[hidden]> wrote:
> >
> > Am Di., 12. Dez. 2023 um 05:42 Uhr schrieb Yongwei Wu via
> > Std-Discussion <std-discussion_at_[hidden]>:
> > >
> > > In the case of erase in the following form:
> > >
> > > constexpr iterator erase(const_iterator);
> > >
> > > basic_string does not say anything about iterator and reference
> > > invalidation, while vector specifically says erase "invalidates
> > > iterators and references at or after the point of the erase".
> >
> > That's not quite right. We have [string.require] p4, which says:
> >
> > 4 References, pointers, and iterators referring to the elements of a
> > basic_string sequence may be invalidated
> > by the following uses of that basic_string object:
> > (4.1) — Passing as an argument to any standard library function taking
> > a reference to non-const basic_string
> > as an argument.
> > (4.2) — Calling non-const member functions, except operator[], at,
> > data, front, back, begin, rbegin, end,
> > and rend.
> >
> > So, bullet (4.2) applies for erase, which is a non-const member
> > function that is not excluded by the listed functions.
>
> Thank you.
>
> I would argue this is quite weak and vague. vector::erase specifically
> says it "invalidates iterators and references at or after the point of
> the erase". That implies iterators pointing to elements before the
> point of erase remain valid. That would be stronger than the point you
> mention here. It does not make sense to me that string provides a
> weaker guarantee than vector.
>
> And the main part of the questions is why (under what circumstance).
> Why should an iterator pointing to the point of erase be invalidated
> for the contiguous sequence containers? The memory layout is fixed,
> after all.

The reason, why the string wording is still that vague in
[string.require] is due to history, since in pre-C++11 a valid string
implementation could use reference-counting.

A reference-counting based implementation is no longer valid, but now
we have to acknowledge the possibility of short-string-optimization is
a special case for basic_string which does not apply to std::vector,
so we cannot expect that all that wording about
iterator/reference/pointer invalidation would be *exactly* the same. I
expect that a paper would be well-come that attempts to cleanup the
historical wording used in basic_string about when invalidation may
happen.

- Daniel

Received on 2023-12-12 09:44:33