C++ 向量迭代器根据条件擦除两个元素
如果满足某些条件,我目前正在尝试从向量中删除2个元素。我可以成功地删除单个元素,而不会出现“vector iterator not Dereferenceable”错误。我知道问题是由于一次删除两个元素造成的,这会使迭代器出错,但我不确定一次删除多个元素的正确方法C++ 向量迭代器根据条件擦除两个元素,c++,vector,iterator,erase,C++,Vector,Iterator,Erase,如果满足某些条件,我目前正在尝试从向量中删除2个元素。我可以成功地删除单个元素,而不会出现“vector iterator not Dereferenceable”错误。我知道问题是由于一次删除两个元素造成的,这会使迭代器出错,但我不确定一次删除多个元素的正确方法 vector<SomeObj*> objs; vector<SomeObj*>::iterator it = objs.begin(); while (it != objs.end()) { vect
vector<SomeObj*> objs;
vector<SomeObj*>::iterator it = objs.begin();
while (it != objs.end())
{
vector<SomeObj*>::iterator it2 = objs.begin();
bool deleted = 0;
while (it2 != objs.end())
{
if ((*it)->somecondition(**it2))
{
delete *it2;
*it2 = NULL;
it = objs.erase(it2);
delete *it;
*it = NULL;
it = objs.erase(it); //Will error here due to invalidating the iterator
deleted = 1;
break;
}
++it2;
}
if (!deleted)
++it;
}
vectorbojs;
vector::iterator it=objs.begin();
while(it!=objs.end())
{
向量::迭代器it2=objs.begin();
bool-deleted=0;
while(it2!=objs.end())
{
if((*it)->somecondition(**it2))
{
删除*it2;
*it2=NULL;
它=对象擦除(it2);
删除*它;
*它=空;
it=objs.erase(it);//由于使迭代器无效,此处将出错
删除=1;
打破
}
++it2;
}
如果(!已删除)
++它;
}
如果要改变容器,使用嵌套迭代器是很棘手的
我已经编写了一些示例代码,可以满足您的需要。我所做的是延迟删除,将要删除的元素设置为nullptr
,然后在循环中遇到这些元素时删除它们
#include <iostream>
#include <vector>
class Example
{
public:
Example(int size) : size(size) {}
bool somecondition(const Example& other) const
{
return size == other.size;
}
int size;
};
int main()
{
std::vector<Example*> vec;
vec.push_back(new Example(1));
vec.push_back(new Example(2));
vec.push_back(new Example(3));
vec.push_back(new Example(2));
for (auto it1 = vec.begin(); it1 != vec.end();)
{
if (!*it1)
{
it1 = vec.erase(it1);
continue;
}
for (auto it2 = vec.begin(); it2 != vec.end(); ++it2)
{
if (!*it2)
{
vec.erase(it2);
// we need to start the outer loop again since we've invalidated its iterator
it1 = vec.begin();
break;
}
if (it1 != it2 && (*it1)->somecondition(**it2))
{
delete *it1;
*it1 = nullptr;
delete *it2;
*it2 = nullptr;
break;
}
}
++it1;
}
for (auto example : vec)
{
std::cout << example->size << std::endl;
}
return 0;
}
#包括
#包括
课例
{
公众:
示例(int size):size(size){}
布尔某些条件(常量示例和其他)常量
{
返回大小==其他.size;
}
整数大小;
};
int main()
{
std::vec;
向量推回(新示例(1));
向量推回(新示例(2));
向量推回(新示例(3));
向量推回(新示例(2));
对于(自动it1=vec.begin();it1!=vec.end();)
{
如果(!*it1)
{
it1=矢量擦除(it1);
继续;
}
对于(自动it2=vec.begin();it2!=vec.end();++it2)
{
如果(!*it2)
{
矢量擦除(it2);
//我们需要再次启动外部循环,因为我们已经使它的迭代器无效
it1=vec.begin();
打破
}
如果(it1!=it2&(*it1)->somecondition(*it2))
{
删除*it1;
*it1=空PTR;
删除*it2;
*it2=空PTR;
打破
}
}
++it1;
}
例如(自动示例:vec)
{
std::cout size问题是第一次调用erase()时很可能会使另一个迭代器无效。请参阅本文,快速总结在各种容器中无效的内容。我认为最简单的解决方案是首先遍历容器并标记要擦除的条目,但不要擦除它们,然后在第二次扫描中只擦除标记的所有内容。出于性能原因,在本文中第二次扫描您应该使用std::remove_if或使用反向迭代器。实际情况是什么?如果两个元素的大小相同