Идиома стирания-удаления: что происходит, когда удаляется возвратный итератор?

Я получил этот вопрос, когда я читал erase-remove idiom (пункт 32) из ​​книги Скотта Мейерса "Эффективный STL".

vector<int> v; 
...
v.erase(remove(v.begin(), v.end(), 99), v.end());

remove в основном возвращает "новый логический конец" и элементы исходного диапазона, которые начинаются с "нового логического конца" диапазона и продолжаются до тех пор, пока реальным концом диапазона не станут элементы, которые будут удалены из контейнера.

Звучит хорошо. Теперь позвольте мне задать мой вопрос:

В приведенном выше примере remove может вернуться v.end() если 99 не найден в vector v, Это в основном проходит past-the-end-iterator стереть метод.

  1. Что происходит, когда past-the-end-iterator передается в erase метод? Стандарт говорит, что это UB?
  2. Если это неопределенное поведение, то erase-remove idiom Пример в книге Скотта Мейера должен был выглядеть так:

  vector<int> v; 
    ...
    vector<int>::iterator newEndIter = remove(v.begin(), v.end(), 99);
    if(newEndIter != v.end() )
    {
     v.erase(newEndIter, v.end();
    }  

Есть идеи по этому поводу?

3 ответа

Стандарт C++ говорит, что erase(q1,q2) member "стирает элементы в диапазоне [q1,q2)" (см. раздел 23.1.1). Поскольку диапазон исключает последний элемент,

v.erase(v.end(), v.end());

действует и ничего не стирает.

Я бы подумал v.erase(v.end(), v.end()) будет хорошо определен и ничего не сотрет.

Ссылка на C++:

Итератор first не должен быть разыменованным, если first==last: стирание пустого диапазона - это запрет.

Другие вопросы по тегам