【发布时间】:2010-12-13 07:07:54
【问题描述】:
我在阅读 Scott Meyers "Effective STL” 书的 erase-remove idiom(第 32 项)时遇到了这个问题。
vector<int> v;
...
v.erase(remove(v.begin(), v.end(), 99), v.end());
remove 基本上返回“新的逻辑结束”和从该范围的“新的逻辑结束”开始并一直持续到该范围的真正结束的原始范围的元素是要从容器中删除的元素。
听起来不错。现在,让我问我的问题:
在上面的示例中,如果在vector v 中找不到 99,remove 可以返回 v.end()。它基本上是将past-the-end-iterator 传递给擦除方法。
- 当
past-the-end-iterator被传递给erase方法时会发生什么?标准是否说它是UB? - 如果是未定义的行为,那么 Scott Meyer 书中的
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();
}
对此有什么想法吗?
【问题讨论】:
-
根据定义 v.end() 不是
past-the-end,它是结束:x -
@Matthieu M. 文档 std::vector::end() 说:“返回一个迭代器,引用向量容器中的过去元素。”
-
@Julien-L:这措辞不好。结束迭代器是最后一个元素。 C++ 规范真的这么说吗?这太令人惊讶了。
-
@MooingDuck 是的,这就是这里使用的措辞:cplusplus.com/reference/vector/vector/end
-
@Julien-L:该站点不仅不是 C++ 规范,而且该站点因误导甚至完全错误的信息而臭名昭著。但是,C++14 draft spec(第 23.2.1 节)确实声明“
end()返回一个迭代器,它是容器的结束值。”
标签: c++ stl erase erase-remove-idiom