C++ Logo

std-proposals

Advanced search

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

From: Jonathan Wakely <cxx_at_[hidden]>
Date: Tue, 9 Dec 2025 09:04:42 +0000
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.

Received on 2025-12-09 09:05:02