Date: Mon, 8 Dec 2025 09:02:40 -0600
> Now "e" points to the newly inserted element.
No, it is an invalidated iterator. Consider the case of a resize.
Cheers,
Jeremy
On Mon, Dec 8, 2025 at 08:52 Nikolay Mihaylov via Std-Proposals <
std-proposals_at_[hidden]> wrote:
> std::vector<int> v;
> v.reserve(10);
>
> v.push_back(1);
>
> auto b = v.begin();
> auto e = v.end();
> v.push_back(1);
>
>
> Hi,
>
> isn't this code means following:
>
> *auto e = v.end();* - get the end iterator at this moment.
> *v.push_back(1); * - push new element
>
> Now "e" points to the newly inserted element.
> I believe this is correct.
> why - because the idea was "e" to be an end() iterator at the moment in
> which it was invoked.
>
>
>
> Regards
> Nikolay
>
>
> On Mon, Dec 8, 2025 at 4:45 PM Nikl Kelbon via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
>
>> The standard needs to better clarify the section on vector iterator
>> invalidation.
>>
>> *Why i think its important:*
>>
>> Some implementations added checks like: "oh, we must store all .end()
>> iterators into global map under mutex and mark them invalid on each
>> push_back, it will be SO useful for our developers!"
>> So, minimal example where it breaks completely:
>>
>> std::vector<int> v;
>> v.reserve(10);
>>
>> v.push_back(1);
>>
>> auto b = v.begin();
>> auto e = v.end();
>> v.push_back(1);
>> ++b;
>> REQUIRE(b == e); // assertion failure:
>> // _STL_VERIFY(this->_Getcont() == _Right._Getcont(), "vector iterators incompatible");
>>
>>
>> Its common pattern when using vector to reserve memory and push values,
>> there are no "better way to do it", thats why it must be valid
>>
>>
>> *Now about standard:*
>>
>> here's a quote from the standard regarding append_range and, apparently,
>> push_back (https://eel.is/c++draft/vector#modifiers-2):
>>
>>
>> If no reallocation happens, then references, pointers, and iterators
>> before the insertion point remain valid but those at or after the insertion
>> point, including the past-the-end iterator, are invalidated
>>
>>
>> It explicitly states that despite there are no relocation happen, the
>> past-the-end iterator is invalidated, although there's no reason for a
>> vector to be so.
>> Yes, a* past-the-end iterator will no longer be past-the-end, but that
>> doesn't make it invalid*. In any implementation, even a foolish one,
>> it's hard to imagine how, without relocation, this iterator could become
>> anything other than just an iterator to the last element of the vector.
>>
>> I think in this case *standard should separate invalidation and what
>> happens here - its not invalidation rly.*
>>
>>
>> --
>> Std-Proposals mailing list
>> Std-Proposals_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
No, it is an invalidated iterator. Consider the case of a resize.
Cheers,
Jeremy
On Mon, Dec 8, 2025 at 08:52 Nikolay Mihaylov via Std-Proposals <
std-proposals_at_[hidden]> wrote:
> std::vector<int> v;
> v.reserve(10);
>
> v.push_back(1);
>
> auto b = v.begin();
> auto e = v.end();
> v.push_back(1);
>
>
> Hi,
>
> isn't this code means following:
>
> *auto e = v.end();* - get the end iterator at this moment.
> *v.push_back(1); * - push new element
>
> Now "e" points to the newly inserted element.
> I believe this is correct.
> why - because the idea was "e" to be an end() iterator at the moment in
> which it was invoked.
>
>
>
> Regards
> Nikolay
>
>
> On Mon, Dec 8, 2025 at 4:45 PM Nikl Kelbon via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
>
>> The standard needs to better clarify the section on vector iterator
>> invalidation.
>>
>> *Why i think its important:*
>>
>> Some implementations added checks like: "oh, we must store all .end()
>> iterators into global map under mutex and mark them invalid on each
>> push_back, it will be SO useful for our developers!"
>> So, minimal example where it breaks completely:
>>
>> std::vector<int> v;
>> v.reserve(10);
>>
>> v.push_back(1);
>>
>> auto b = v.begin();
>> auto e = v.end();
>> v.push_back(1);
>> ++b;
>> REQUIRE(b == e); // assertion failure:
>> // _STL_VERIFY(this->_Getcont() == _Right._Getcont(), "vector iterators incompatible");
>>
>>
>> Its common pattern when using vector to reserve memory and push values,
>> there are no "better way to do it", thats why it must be valid
>>
>>
>> *Now about standard:*
>>
>> here's a quote from the standard regarding append_range and, apparently,
>> push_back (https://eel.is/c++draft/vector#modifiers-2):
>>
>>
>> If no reallocation happens, then references, pointers, and iterators
>> before the insertion point remain valid but those at or after the insertion
>> point, including the past-the-end iterator, are invalidated
>>
>>
>> It explicitly states that despite there are no relocation happen, the
>> past-the-end iterator is invalidated, although there's no reason for a
>> vector to be so.
>> Yes, a* past-the-end iterator will no longer be past-the-end, but that
>> doesn't make it invalid*. In any implementation, even a foolish one,
>> it's hard to imagine how, without relocation, this iterator could become
>> anything other than just an iterator to the last element of the vector.
>>
>> I think in this case *standard should separate invalidation and what
>> happens here - its not invalidation rly.*
>>
>>
>> --
>> Std-Proposals mailing list
>> Std-Proposals_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
Received on 2025-12-08 15:02:57
