vector
and deque
iterator erase
invalidates elements even when no change occursSection: 23.3.5.4 [deque.modifiers], 23.3.11.5 [vector.modifiers] Status: New Submitter: Billy O'Neal III Opened: 2019-10-29 Last modified: 2019-11-04
Priority: 3
View other active issues in [deque.modifiers].
View all other issues in [deque.modifiers].
View all issues with New status.
Discussion:
It seems incorrect that a container would invalidate anything as a result of being asked to erase 0 elements.
This came up in a recent customer bug report against Visual Studio, where given a vector v
,
v.erase(v.begin(), v.begin())
triggered a self-assignment of all the elements in the vector.
deque
has language enumerating erasures of the first and last element which invalidate fewer
iterators, and a fallback that says all iterators are invalidated, which seems to intend to be talking about middle-of-container erasures. However, erasing 0 elements isn't really a middle of container erasure.
vector
says that iterators and references are invalidated after the 'point of the erase', but when 0
elements are erased it's unclear what that even means.
We should say that erasures that erase 0 elements are no ops and be clearer about which elements are
invalidated for vector
.
[2019-11 Priority to 3 during Monday issue prioritization in Belfast]
Proposed resolution:
This wording is relative to N4835.
Modify 23.3.5.4 [deque.modifiers] as indicated:
iterator erase(const_iterator position); iterator erase(const_iterator first, const_iterator last); void pop_front(); void pop_back();-4- Effects: Erases elements as indicated in Table 75 [tab:container.seq.req]. An erase operation that erases the last element of a deque invalidates only the past-the-end iterator and all iterators and references to the erased elements. An erase operation that erases the first element of a deque but not the last element invalidates only iterators and references to the erased elements. An erase operation that erases any elements, but neither the first element nor the last element of a deque invalidates the past-the-end iterator and all iterators and references to all the elements of the deque.
[…][Note:pop_front
andpop_back
are erase operations. — end note]
Modify 23.3.11.5 [vector.modifiers] as indicated:
constexpr iterator erase(const_iterator position); constexpr iterator erase(const_iterator first, const_iterator last); constexpr void pop_back();-3- Effects: Erases elements as indicated in Table 75 [tab:container.seq.req]. Invalidates iterators and references at or after the
[…]point of the erase.first erased element. [Note: For the second overload oferase
, iffirst == last
, no elements are erased, and no iterators or references are invalidated. — end note]