C ++在循环中删除列表中的对象

时间:2014-05-14 12:14:53

标签: c++ stl

如何删除已完成作品的所有对象

我使用以下代码但得到列表迭代器不可递增

如何删除它而不删除它

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
    }
}

4 个答案:

答案 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
    }
}

std::list::erase

  

返回:一个迭代器,指向函数调用擦除的最后一个元素后面元素的新位置。如果操作擦除序列中的最后一个元素,则这是容器结束。