C++ Logo

std-discussion

Advanced search

Re: erase and iterator invalidation

From: Marcin Jaczewski <marcinjaczewski86_at_[hidden]>
Date: Tue, 12 Dec 2023 18:02:35 +0100
wt., 12 gru 2023 o 17:57 Julien Villemure-Fréchette via Std-Discussion
<std-discussion_at_[hidden]> napisał(a):
>
> About SSO: implementations normally use the size of the string to determine if the sequence of chars is held within the string's buffer, so removing a char can potentially require the sequence of chars to be moved from the allocated memory.
>
> Julien V.
>
>

No, at least they check capacity not current size.
otherwise it would make impossible to implement `reserve`
(as all start with `size() == 0`)

> On December 12, 2023 4:44:19 a.m. EST, "Daniel Krügler via Std-Discussion" <std-discussion_at_[hidden]> wrote:
>>
>> 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
>
> --
> Std-Discussion mailing list
> Std-Discussion_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion

Received on 2023-12-12 17:02:48