简体   繁体   English

擦除 std::vector 的 function

[英]Erase function of the std::vector

I have a std::vector and an iterator that points to an element in the vector.我有一个std::vector和一个指向向量中元素的迭代器。 My question is how can I delete an element from the vector and keep the iterator?我的问题是如何从向量中删除一个元素并保留迭代器?

I've tried using a second iterator to find the specific element that I want to delete and after erasing it with the erase function, the first iterator becomes invalid.我尝试使用第二个迭代器来查找我想要删除的特定元素,并在使用擦除 function 擦除它后,第一个迭代器变得无效。

My question is how can I delete an element from the vector and keep the iterator?我的问题是如何从向量中删除一个元素并保留迭代器?

You can't using std::vector::iterator .您不能使用std::vector::iterator The iterator will be invalidated by erasing the element.迭代器将通过擦除元素而失效。

But you could achieve this by writing your own iterator class that stores a pointer to the vector and an index.但是您可以通过编写自己的迭代器 class 来实现这一点,该迭代器存储指向向量和索引的指针。

std::vector::erase will invalidate all iterators at or after the erased element: std::vector::erase将使擦除元素处或之后的所有迭代器无效:

Invalidates iterators and references at or after the point of the erase, including the end() iterator.在擦除点处或之后使迭代器和引用无效,包括 end() 迭代器。

However, erase will return an iterator pointing to the element following the last removed element.但是, erase将返回一个迭代器,该迭代器指向最后一个被删除元素之后的元素。 Maybe that is enough to satisfy your use case?也许这足以满足您的用例?

I have a std::vector and an iterator that points to an element in the vector.我有一个 std::vector 和一个指向向量中元素的迭代器。 My question is how can I delete an element from the vector and keep the iterator?我的问题是如何从向量中删除一个元素并保留迭代器?

Please note that when an element is deleted, no iterator can point to it as it ceases to exist.请注意,当一个元素被删除时,没有迭代器可以指向它,因为它不再存在。 So, to reference it's location normal practice is just use the returned iterator from the erase() method.因此,要引用它的位置,通常的做法是使用从erase()方法返回的迭代器。 This allows use of the insert() method which will put a value in the position of the previously erased object.这允许使用insert()方法,该方法将在先前擦除的 object 的 position 中放入一个值。 With one iterator, just use this:使用一个迭代器,只需使用这个:

auto loc_after = v.erase(iter);  // since the element has been erased loc_after points to the position the erased element had

I've tried using a second iterator to find the specific element that I want to delete and after erasing it with the erase function, the first iterator becomes invalid.我尝试使用第二个迭代器来查找我想要删除的特定元素,并在使用擦除 function 擦除它之后,第一个迭代器变得无效。

In the case of two iterators the elements can be easily erased by erasing the physically last iterator first since the earlier iterator is not invalidated.在两个迭代器的情况下,可以通过首先擦除物理上最后一个迭代器来轻松擦除元素,因为较早的迭代器没有失效。 This is encapsulated in a function.这封装在 function 中。 The returned iterator points to one past the position of the "first" iterator regardless of order between the first and second iterator.返回的迭代器指向超过“第一个”迭代器的 position 的一个,无论第一个和第二个迭代器之间的顺序如何。

#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

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM