Title
vector and deque iterator erase invalidates elements even when no change occurs
Status
new
Section
[deque.modifiers][vector.modifiers]
Submitter
Billy O'Neal III

Created on 2019-10-29.00:00:00 last changed 53 months ago

Messages

Date: 2019-11-04.13:23:43

Proposed resolution:

This wording is relative to N4835.

  1. Modify [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 and pop_back are erase operations. — end note]

    […]

  2. Modify [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 of erase, if first == last, no elements are erased, and no iterators or references are invalidated. — end note]

    […]

Date: 2019-11-04.13:23:43

[ 2019-11 Priority to 3 during Monday issue prioritization in Belfast ]

Date: 2019-10-29.00:00:00

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.

History
Date User Action Args
2019-11-04 13:23:43adminsetmessages: + msg10728
2019-10-31 19:25:43adminsetmessages: + msg10719
2019-10-29 00:00:00admincreate