std::vector::erase
примет либо один итератор, обозначающий позицию удаляемого элемента, либо два итератора, обозначающие диапазон. Но вы не можете сделать это:
std::vector<int> vec = { 1, 2, 3 };
vec.erase(1);
Скорее вы должны сделать что-то вроде
vec.erase( vec.begin()+1 );
Это кажется ненужной дополнительной работой — просто интересно, есть ли какая-то причина из POV дизайна класса, почему эта перегрузка не будет включена?
редактировать: Выбрал наиболее полный ответ, все были хорошими. Также, когда я пишу это, у этого поста есть 4 близких голоса за то, что он «не конструктивен»; однако, учитывая качество ответов, я думаю, что это был явно полезный вопрос, безусловно, для меня.
Есть две причины, которые я могу придумать:
1) erase
является общей функцией-членом для контейнеров. Использование индексов имеет смысл только для некоторых контейнеров, поэтому при использовании итераторов вам не нужно беспокоиться о типе контейнера, с которым вы работаете. Например, индексы имеют смысл только для контейнеров с произвольным доступом, используя итераторы, вы повышаете гибкость своего кода и т. Д.
2) erase
хорошо работает со стандартными алгоритмами, такими как std::remove
, std::remove_if
, std::unique
и т. д. Чаще встречается желание стереть элементы на основе некоторого предиката и т. д., а не жестко кодировать индексный номер. Ищите «стереть-удалить идиому» для получения дополнительной информации.
По сути, итераторы считаются превосходящими индексирование по многим причинам, и это то, что вы увидите, широко используется в стандартной библиотеке C ++. Индексы лучше использовать для симулированного доступа к массиву, если это имеет смысл.
Насколько я понимаю, stl хочет разделить индекси и целые числа, так как они не одно и то же (семантически): если вы хотите делать арифметику, используйте целое число, если вы хотите получить доступ к элементу в контейнере stl, используйте итератор. Также он служит абстракцией: часто целые числа могут служить индексом, иногда это не имеет смысла.
Представь, если бы ты
typedef std::set<int> MyContainer
MyContainer c;
// ...
c.erase(5); // Or a programmatic int
Теперь, если вы измените базовый контейнер MyContainer (путем обновления typedef
) чтобы vector
вдруг ваш erase
полностью изменился в смысловом значении и до сих пор компилируется! Я не могу представить ни одного другого случая, когда такое простое изменение типа контейнера привело бы к такому другому поведению.
Чтобы избежать этого, erase
имеет только входные значения или итераторы, но не индекс.