std::vector的擦除函数
Erase function of the std::vector
我有一个 std::vector
和一个指向向量中元素的迭代器。我的问题是如何从向量中删除一个元素并保留迭代器?
我已经尝试使用第二个迭代器来查找我想要删除的特定元素,并且在使用擦除函数擦除它之后,第一个迭代器变得无效。
My question is how can I delete an element from the vector and keep the iterator?
您不能使用 std::vector::iterator
。迭代器将通过擦除元素而失效。
但是您可以通过编写自己的迭代器 class 来实现这一点,它存储一个指向向量的指针和一个索引。
std::vector::erase
将使擦除元素处或之后的所有迭代器失效:
Invalidates iterators and references at or after the point of the
erase, including the end() iterator.
但是,erase
将 return 指向最后一个删除元素之后的元素的迭代器。也许这足以满足您的用例?
我有一个 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
我试过使用第二个迭代器找到我想删除的特定元素,在用擦除函数擦除它后,第一个迭代器变得无效。
在两个迭代器的情况下,可以通过首先擦除物理上最后一个迭代器来轻松擦除元素,因为较早的迭代器不会失效。这被封装在一个函数中。无论第一个和第二个迭代器之间的顺序如何,返回的迭代器都指向 "first" 迭代器位置之后的一个。
#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
}
我有一个 std::vector
和一个指向向量中元素的迭代器。我的问题是如何从向量中删除一个元素并保留迭代器?
我已经尝试使用第二个迭代器来查找我想要删除的特定元素,并且在使用擦除函数擦除它之后,第一个迭代器变得无效。
My question is how can I delete an element from the vector and keep the iterator?
您不能使用 std::vector::iterator
。迭代器将通过擦除元素而失效。
但是您可以通过编写自己的迭代器 class 来实现这一点,它存储一个指向向量的指针和一个索引。
std::vector::erase
将使擦除元素处或之后的所有迭代器失效:
Invalidates iterators and references at or after the point of the erase, including the end() iterator.
但是,erase
将 return 指向最后一个删除元素之后的元素的迭代器。也许这足以满足您的用例?
我有一个 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
我试过使用第二个迭代器找到我想删除的特定元素,在用擦除函数擦除它后,第一个迭代器变得无效。
在两个迭代器的情况下,可以通过首先擦除物理上最后一个迭代器来轻松擦除元素,因为较早的迭代器不会失效。这被封装在一个函数中。无论第一个和第二个迭代器之间的顺序如何,返回的迭代器都指向 "first" 迭代器位置之后的一个。
#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
}