Стереть функцию из std :: vector - PullRequest
0 голосов
/ 21 сентября 2019

У меня есть std::vector и итератор, который указывает на элемент в векторе.У меня вопрос, как я могу удалить элемент из вектора и сохранить итератор?

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

Ответы [ 3 ]

2 голосов
/ 21 сентября 2019

std::vector::erase сделает недействительными все итераторы в или после стертого элемента:

Делает недействительными итераторы и ссылки в или после точки удаления, включая итератор end ().

Однако erase вернет итератор, указывающий на элемент, следующий за последним удаленным элементом.Может быть, этого достаточно, чтобы удовлетворить ваш вариант использования?

2 голосов
/ 22 сентября 2019

У меня есть 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

}
2 голосов
/ 21 сентября 2019

Мой вопрос: как я могу удалить элемент из вектора и сохранить итератор?

Вы не можете использовать std::vector::iterator.Итератор будет признан недействительным, удалив элемент.

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

...