迭代向量并删除其某些元素的安全方法是什么

时间:2016-06-16 08:09:49

标签: c++ loops for-loop vector iterator

是否可以通过向量的元素迭代一次,同时删除一些元素,以防止重复处理? (我知道片段是伪造的,但说明了我想要的东西)

std::vector<MyRecord*>* BLV = GetVector();
for (std::vector<MyRecord*>::iterator it = BLV->begin(); it != BLV->end(); ++it)
{
  MyRecord* BL = *it;
  if(Selected)
  { 
    delete BL;
    BLV->erase(it);
  }
}

2 个答案:

答案 0 :(得分:8)

注意std::vector::erase将使要删除的元素的迭代器无效,然后++it;将导致UB。

  

在擦除点或之后使迭代器和引用无效,包括end()迭代器。

您可以使用erase()的返回值。

  

跟随最后删除的元素的迭代器。如果迭代器pos引用最后一个元素,则返回end()迭代器。

然后将循环更改为

for (std::vector<MyRecord*>::iterator it = BLV->begin(); it != BLV->end(); )
{
  MyRecord* BL = *it;
  if(Selected)
  { 
    delete BL;
    it = BLV->erase(it);
  } else
  {
    ++it;
  }
}

答案 1 :(得分:0)

songyuanyao已经给你一个很好的答案:简而言之,你必须将迭代器重置为erase返回的值。

但是,如果适用,我建议使用unique_ptr的矢量和erase-remove习惯用法(这也更有效,因为它只移动元素一次)。

std::vector<std::unique_ptr<MyRecord>>* BLV = GetVector();
BLV->erase(
    std::remove_if(BLV->begin(), BLV->end(), 
        [&](const std::unique_ptr<MyRecord>& rec) { return Selected; }
    ),
    BLV->end()
);