Date: Mon, 8 Dec 2025 19:45:29 +0500
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.*
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.*
Received on 2025-12-08 14:45:45
