【问题标题】:"vector iterators incompatible" assertion failure in erasing element in a vector while iterating using swap-and-pop“向量迭代器不兼容”断言在使用交换和弹出迭代时擦除向量中的元素失败
【发布时间】:2012-12-03 14:08:54
【问题描述】:

我在这里使用交换和弹出技术:Erasing element in a vector while iterating using swap-and-pop

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

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 时,一切正常。

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

【问题讨论】:

  • 这个断言错误在哪一行?
  • @Leonid: for(auto iter=vec.begin(); iter!=vec.end();)
  • 这看起来像 auto 正在为您生成错误的类型。您是否尝试过拼写类型而不是使用auto?你用的是什么编译器? vec 是如何定义的?
  • 附带说明,(*iter).iter-> 相同。 ;)

标签: c++ vector


【解决方案1】:

当您在最后一个元素上调用 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() 未被缓存

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-02
    • 2012-01-15
    相关资源
    最近更新 更多