擦除删除习惯用法:删除返回结束迭代器时会发生什么?

时间:2009-11-05 04:32:19

标签: c++ stl erase erase-remove-idiom

当我从Scott Meyers "Effective STL”一书中读到erase-remove idiom(第32项)时,我得到了这个问题。

vector<int> v; 
...
v.erase(remove(v.begin(), v.end(), 99), v.end());

remove基本上返回“新逻辑结束”和从该范围的“新逻辑结束”开始的原始范围的元素,并继续直到范围的实际结束是要从中删除的元素容器

听起来不错。现在,让我问一下我的问题:

在上面的示例中,如果在remove中找不到99,则v.end()可以返回vector v。它基本上是将past-the-end-iterator传递给擦除方法。

  1. past-the-end-iterator传递给erase时会发生什么?标准是否说它是UB?
  2. 如果它是未定义的行为,那么Scott Meyer的书中的erase-remove idiom示例应该如下:
  3.   vector<int> v; 
        ...
        vector<int>::iterator newEndIter = remove(v.begin(), v.end(), 99);
        if(newEndIter != v.end() )
        {
         v.erase(newEndIter, v.end();
        }  
    

    有关于此的任何想法吗?

3 个答案:

答案 0 :(得分:10)

我认为v.erase(v.end(), v.end())定义明确,不会删除任何内容。

答案 1 :(得分:10)

C ++标准说erase(q1,q2)成员“删除了[q1,q2]范围内的元素”(参见第23.1.1节)。由于范围排除了最后一个元素,

v.erase(v.end(), v.end());

有效并且一无所获。

答案 2 :(得分:2)

C++ Reference声称:

  

如果first:删除空范围是无操作,则迭代器first==last不需要可解除引用。