我们都知道当使用erase in for时,我们必须重置iter,就像iter = vector.erase(iter),因为erase选项会使iteraor无效。然而,我发现,not reset也是有效的,代码如下:
int main() {
vector<int> a;
a.push_back(1);
a.push_back(2);
a.push_back(3);
a.push_back(2);
a.push_back(10);
a.push_back(11);
for (vector<int>::iterator iter = a.begin(); iter != a.end();) {
if (*iter == 2) {
// iter = a.erase(iter); the same
a.erase(iter);
continue;
} else {
iter++;
}
}
for (vector<int>::iterator iter = a.begin(); iter != a.end(); iter++) {
cout << *iter << " ";
}
cout << endl;
return 0;
}代码成功运行,输出为:1 3 10 11。
所以我的问题是,在这段代码中,"a.erase(iter)“和"iter = a.earse(iter)”得到了相同的结果?
发布于 2015-08-01 11:59:15
您看到的是未定义的行为。
来自http://en.cppreference.com/w/cpp/container/vector/erase (重点是我的)
从容器中删除指定的元素。
1)删除pos处的元素。
2)删除范围[first; last)中的元素。会在擦除结束点或之后使迭代器和引用失效,包括()迭代器。
通过使用
a.erase(iter);
continue;您正在访问无效的迭代器。
发布于 2015-08-01 12:03:31
您的代码依赖于向量的元素减少,从而不执行保留减少来消除不需要的容量。坦率地说,我使用过的几乎所有标准库实现都是这样做的(减小大小值并将元素“左”移),但标准并不保证这样做。相反,情况恰恰相反。一旦擦除了当前迭代器的位置,该迭代器和任何其他过去的迭代器都是无效的。因此,您的代码表现出未定义的行为。
关于标准特别说明你的迭代器在哪里失效:
C++11§23.3.6.5 vector.modifiers
……
iterator erase(const_iterator position);
iterator erase(const_iterator first, const_iterator last);
移动赋值效果:在erase.
但我很好奇:你为什么不直接使用remove/erase idiom?:
a.erase(std::remove(a.begin(), a.end(), 2), a.end());https://stackoverflow.com/questions/31758025
复制相似问题