У меня есть std :: vector и итератор, который указывает на элемент в векторе.Мой вопрос: как я могу удалить элемент из вектора и сохранить итератор?
Обратите внимание, что когда элемент удаляется, ни один итератор не может указывать на него, поскольку он перестает существовать.Таким образом, для ссылки на его местоположение обычная практика - просто использовать возвращенный итератор из метода erase()
.Это позволяет использовать метод insert()
, который поместит значение в позицию ранее стертого объекта.С одним итератором, просто используйте это:
auto loc_after = v.erase(iter); // since the element has been erased loc_after points to the position the erased element had
Я пытался использовать второй итератор, чтобы найти конкретный элемент, который я хочу удалить, и после стирания его с помощью функции стирания, первый итераторстановится недействительным.
В случае двух итераторов элементы можно легко удалить, удалив физически последний итератор первым, поскольку предыдущий итератор не считается недействительным.Это заключено в функцию.Возвращенный итератор указывает на одну позицию после «первого» итератора независимо от порядка между первым и вторым итератором.
#include <vector>
#include <iostream>
// This returns an iterator positioned after where first_iter was before being erased
// this allows the insert(pos, val) method to insert a value in the the location just prior to pos
std::vector<int>::iterator second_iterator_loc(std::vector<int>& v, std::vector<int>::iterator first_iter, std::vector<int>::iterator second_iter)
{
std::vector<int>::iterator iter;
if (first_iter < second_iter)
{
v.erase(second_iter);
iter = v.erase(first_iter);
}
else if (second_iter < first_iter)
{
auto dist = first_iter - second_iter;
v.erase(first_iter);
iter = v.erase(second_iter) + dist - 1;
}
else
{
;// handler in case both iterators point to the same object
}
return iter;
}
int main()
{
std::vector<int> v{ 1,2,3,4,5 };
std::vector<int> v2 = v;
std::vector<int>::iterator iter1 = v.begin() + 1; // points to 2 in v
std::vector<int>::iterator iter2 = v.begin() + 3; // points to 4 in v
std::vector<int>::iterator iter;
iter = second_iterator_loc(v, iter1, iter2);
v.insert(iter, 9); // inserts a 9 in the previous location of the "first" iterator (where "2" was)
for (auto x : v)
std::cout << x << '\n'; // prints: 1 9 4 5
v = v2;
iter1 = v.begin() + 3; // reverse iterator positions
iter2 = v.begin() + 1;
iter = second_iterator_loc(v, iter1, iter2);
v.insert(iter, 9); // inserts a 9 in the previous location of the "first" iterator (where "4" was)
for (auto x : v)
std::cout << x << '\n'; // prints: 1 3 9 5
}