如何删除已完成作品的所有对象
我使用以下代码但得到列表迭代器不可递增
如何删除它而不删除它
list<A*> myList;
for(list<A*>::iterator it = myList.begin(); it !=myList.end(); ++it ){
(*it )->DoSomething();
if((*it )->WorksFnished()){
//myList.erase(it ); <- It's works but I get exception after the loop
//myList.remove(*it ); <- It's works but I get exception after the loop
}
}
答案 0 :(得分:4)
erase
返回迭代器
list<A*> myList;
list<A*>::iterator it = myList.begin();
while( it != myList.end() ) {
(*it)->DoSomething();
if( (*it)->WorksFnished() ) {
it = myList.erase(it);
} else {
++it;
}
}
答案 1 :(得分:3)
您可以利用erase
返回新迭代器的事实,如此处的其他答案中所述。对于性能关键代码,这可能是最佳解决方案。但就个人而言,我倾向于将循环拆分为单独的处理和删除步骤,以提高可读性和清晰度:
// Assumes C++ 11 compatible compiler
list<A*> myList;
// Processing
for(const auto* each : myList){
each->DoSomething();
}
// Deletion
myList.remove_if([](A* each) {
return each->WorksFnished();
});
如果您不想使用remove_if
,可以选择以下方法:
std::swap
与当前列表一起复制toBeRemoved
,并添加应删除的所有对象。当您完成对实际列表的迭代时,请迭代toBeRemoved
并为每个元素调用myList.erase
答案 2 :(得分:1)
一些解决方法..
增加具有WorkFnished
的列表中的对象数。
循环之后。如果累加器与列表大小匹配,请将其清除。
size_t nFinished = 0;
list<A*> myList;
for(list<A*>::iterator it = myList.begin(); it !=myList.end(); ++it ){
(*it )->DoSomething();
if((*it )->WorksFnished()){
nFinished++;
}
}
if (nFinished == myList.size())
{
myList.clear();
}
答案 3 :(得分:1)
如果使用erase
,则必须将其分配回迭代器。在这种情况下,我们必须根据当前元素是否被删除来处理增量。
list<A*> myList;
for (auto it = myList.begin(); it != myList.end(); )
{
(*it)->DoSomething();
if( (*it)->WorksFnished() ) {
it = myList.erase(it); // Sets it to the next element
} else {
++it; // Increments it since no erasing
}
}
返回:一个迭代器,指向函数调用擦除的最后一个元素后面元素的新位置。如果操作擦除序列中的最后一个元素,则这是容器结束。