2256. On vector iterator invalidation

Section: 23.3.11.5 [vector.modifiers] Status: NAD Submitter: Howard Hinnant Opened: 2013-04-29 Last modified: 2020-05-08

Priority: 3

View all other issues in [vector.modifiers].

View all issues with NAD status.

Discussion:

23.3.11.5 [vector.modifiers]/p3 says:

iterator erase(const_iterator position);
iterator erase(const_iterator first, const_iterator last);

Effects: Invalidates iterators and references at or after the point of the erase.

Consider this example:

#include <vector>
#include <cassert>

int main()
{
  typedef std::vector<int> C;
  C c = {1, 2, 3, 4};
  C::iterator i = c.begin() + 1;
  C::iterator j = c.end() - 1;
  assert(*i == 2);
  assert(*j == 4);
  c.erase(c.begin());
  assert(*i == 3); // Why is this not perfectly fine?!
}

Why has the iterator i been invalidated? It still refers to a perfectly reasonable, fully constructed object. If vector::iterator were to be implemented as a pointer (which is legal), it is not possible for that last line to do anything but run fine.

The iterator j on the other hand now points at end, and any iterators that may now point beyond end(), into uninitialized memory, are clearly invalid.

But why do we say that an iterator that must point to a valid object is invalid? This looks to me like we simply got sloppy in our specification.

[2016-05 Issues Telecon]

This is related to 2698

[2017-03-04, Kona]

NAD. "Works as designed" Also, the example does not work in today's world of launder.

Proposed resolution: