Date: Tue, 12 Dec 2023 11:57:02 -0500
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.
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
Julien V.
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 16:57:10