On Tue, 9 Dec 2025 at 08:52, David Brown via Std-Proposals <std-proposals@lists.isocpp.org> 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.