Какой итератор возвращает вектор :: erase (), если передан пустой диапазон? - PullRequest
7 голосов
/ 20 января 2020

Согласно cppreference.com и cplusplus.com , функция std::erase(first, last) возвращает «итератор, следующий за последним удаленным элементом».

Однако это Непонятно, что такое возвращаемое значение в особом случае, когда вообще нет удаленного элемента, то есть, когда first == last (пустой диапазон). По состоянию на 19 января 2020 г. ни один из вышеперечисленных источников не упоминает этот особый случай.

Например, в следующем коде:

std::vector<int> v{1, 2, 3, 4};
auto it1 = v.erase(v.begin(), v.begin());
auto it2 = v.erase(v.end(), v.end());

Что будет значением it1 и it2

1 Ответ

9 голосов
/ 20 января 2020

Это указывается в [sequence.reqmts] :

Итератор, возвращаемый a.erase(q1, q2), указывает на элемент, на который указывает q2, до того, как любые элементы будут стерта. Если такого элемента не существует, возвращается a.end().

(Примечание: я связал окончательный рабочий проект C ++ 17, но эта формулировка существует, поскольку, по крайней мере, C ++ 98, см. комментарий @Peter)

Таким образом, мы должны иметь it1 == v.begin() и it2 == v.end().

Живой тест :

#include <iostream>
#include <vector>

int main()
{
    std::vector<int> v{1, 2, 3, 4};
    auto it1 = v.erase(v.begin(), v.begin());
    auto it2 = v.erase(v.end(), v.end());
    std::cout << std::distance(v.begin(), it1) << std::endl;
    std::cout << std::distance(v.begin(), it2) << std::endl;
}

Вывод:

0
4

Чтобы прояснить это поведение, я обновил документацию cppreference , которая теперь:

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

Return Значение

Итератор, следующий за последним удаленным элементом.

Если pos ссылается на последний элемент, возвращается итератор end ().

Если последний == end () до удаления, затем возвращается обновленный итератор end ().

Если [first, last) пустой диапазон, тогда возвращается last.

...