迭代器指向已擦除项目的有效性

时间:2011-03-21 14:53:36

标签: c++ stl iterator erase

that page上,据说:

  

这会使所有迭代器和   在位置之后引用元素   或者首先。

这意味着擦除后positionfirst迭代器是否有效?

(显然,我问这是因为我想在for_each循环期间删除向量中的某些项目。)

谢谢。

5 个答案:

答案 0 :(得分:2)

根据http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-defects.html#414 positonfirst应该被认为是无效的 - 标准中的措辞不清楚,但是在一个句子中提到了迭代器和引用,并且提到了擦除元素没有意义,删除指向擦除元素的无效迭代器是“理所当然”。我会避免依赖擦除的迭代器是有效的 - 当你从带有一个元素的向量中擦除begin()时,我不会理所当然地认为迭代器突然等于end()

答案 1 :(得分:2)

通常,如果您尝试从循环中的vector中删除多个项目,则使用remove_if会比在每个项目上使用erase提供更好的效果。考虑这一点而不是迭代擦除。

然而,回答你的问题,是的,它们是有效的,但在再次测试end之前要小心增加迭代器,因为擦除可能使你的迭代器现在等于end。编辑:@Erik的回答表明它实际上可能无效,但措辞不清楚。

答案 2 :(得分:0)

是。但是它们不会引用与erase()之前相同的元素,因为该元素将被删除!

答案 3 :(得分:0)

如果在迭代时擦除,请考虑以下语法:

vector<int> items = ...;

for(vector<int>::iterator it = items.begin() ; it != items.end() ; /*inline*/)
{
   if(/* should erase*/)
      it = items.erase(it);
   else
      ++it;
}

这是有效的,因为erase()将迭代器返回到当前元素之后的下一个元素。所以,如果你擦除了,它会“递增”,否则你会像平常一样递增。正如其他人所指出的那样,这不是很有效(因为当前的所有元素都被向前复制),并且有更好的方法。例如,正如Mark B所提到的,最好使用remove_if

答案 4 :(得分:0)

这就是它所说的,但这是错误的。根据标准, 它们无效(这是有道理的,因为保持有效, 他们必须指出一个不再存在的元素。