当我从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
传递给擦除方法。
past-the-end-iterator
传递给erase
时会发生什么?标准是否说它是UB? erase-remove idiom
示例应该如下:
vector<int> v;
...
vector<int>::iterator newEndIter = remove(v.begin(), v.end(), 99);
if(newEndIter != v.end() )
{
v.erase(newEndIter, v.end();
}
有关于此的任何想法吗?
答案 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)
如果
first
:删除空范围是无操作,则迭代器first==last
不需要可解除引用。