C++ Logo

std-proposals

Advanced search

Re: [std-proposals] vector::push_back must not invalidate past-the-end iterator

From: Nikl Kelbon <kelbonage_at_[hidden]>
Date: Tue, 9 Dec 2025 14:20:28 +0500
> This is required to work even if the range overlaps with the vector.

So, my general code must if constexpr (is_same_v<vector>) or what?

Additionally, you really good with:

vector x = ...;

x.append_range(subrange(x.begin(), x.end()));
"this is required to work even if range overlaps"

But

vector x = ...;
x.reserve(x.size() * 10);
x.insert(x.end(), x.begin(), x.end()); // undefined behavior

Nice, really great interface




вт, 9 дек. 2025 г. в 14:05, Jonathan Wakely via Std-Proposals <
std-proposals_at_[hidden]>:

>
>
> On Tue, 9 Dec 2025 at 08:52, David Brown via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
>
>> On 09/12/2025 05:18, Nikl Kelbon via Std-Proposals wrote:
>> > Im glad you now asking for a motivation and not asking "what is past
>> the
>> > end iterator" or smth what was discussed before
>> >
>> > In real code i created my container template, so its iterator combines
>> > several iterators of its parts. std::vector was one of those parts
>> >
>> > Then i wrote append(iterator, iterator) and my code sures it is
>> > completely right, no reallocation etc etc.
>> >
>> > But msvc stl implementation find a way to assert it (by storing all
>> > .end() iterators in global map under mutex and invalidate them on each
>> > push_back)
>> >
>> > I dont know any other way to code it. Its impossible. THERE ARE NO
>> OTHER
>> > WAY!
>>
>>
>> In my field of work, I make little use of containers because we avoid
>> dynamic memory to the greatest possible extent. So I could be missing
>> something obvious to everyone else - forgive me if this suggestion is
>> daft.
>>
>> void append(iterator b, iterator e) {
>> for (auto n = e - b; n; n--, ++b) {
>> vec.push_back(*b);
>> }
>> }
>>
>> Won't that give the same set of push_back's without needing "e" to
>> remain valid?
>>
>
> As Ville said, this requires e - b to be valid, which means it only works
> with random access iterators. In this case, that's fine because the
> iterator type is vector::iterator.
>
> For the general case where you want to append the elements from an
> arbitrary iterator type, vector already provides a solution:
>
> template<typename Iter>
> void append(Iter b, Iter e)
> {
> vec.append_range(subrange(b, e));
> }
>
> This is required to work even if the range overlaps with the vector.
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>

Received on 2025-12-09 09:20:43