4

我从这里使用交换和弹出技术:擦除向量中的元素,同时使用交换和弹出进行迭代

下面的代码导致“向量迭代器不兼容”断言失败。

for(auto iter=vec.begin(); iter!=vec.end();)
{
    if((*iter).isAlive())//update the entity if the entity is alive
    {
        (*iter).update();
        ++iter;
    }
    else  //otherwise, get rid of it
    {
        std::swap(*iter, vec.back());
        vec.pop_back();
    }
}

但是,当我使用 std::list 而不是 std::vector 时,一切运行良好。

为什么在使用向量时会出现断言失败?

4

1 回答 1

0

当您调用vec.pop_back()最后一个元素时,iter由于它指向vec.back(). STL文档说这vector::pop_back()会使.back()end()

解决此问题的一种方法是检测以下特殊情况size()==1

for(auto iter=vec.begin(); iter!=vec.end(); )
{
    if((*iter).isAlive())//update the entity if the entity is alive
    {
        (*iter).update();
        ++iter;
    }
    else if(vec.size() > 1) // can swap&pop
    {
        std::swap(*iter, vec.back());
        vec.pop_back();
    }
    else // need to reset iterator
    {
        vec.pop_back();
        iter = vec.begin();
    }
}

假设:

  • auto正在推断正确的类型
  • 循环不变量iter!=vec.end()没有被缓存
于 2018-01-29T01:07:39.650 回答