首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >向量擦除无需设置iter返回值即可工作

向量擦除无需设置iter返回值即可工作
EN

Stack Overflow用户
提问于 2015-08-01 11:52:41
回答 2查看 62关注 0票数 0

我们都知道当使用erase in for时,我们必须重置iter,就像iter = vector.erase(iter),因为erase选项会使iteraor无效。然而,我发现,not reset也是有效的,代码如下:

代码语言:javascript
复制
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)”得到了相同的结果?

EN

回答 2

Stack Overflow用户

发布于 2015-08-01 11:59:15

您看到的是未定义的行为。

来自http://en.cppreference.com/w/cpp/container/vector/erase (重点是我的)

从容器中删除指定的元素。

1)删除pos处的元素。

2)删除范围[first; last)中的元素。会在擦除结束点或之后使迭代器和引用失效,包括()迭代器。

通过使用

代码语言:javascript
复制
a.erase(iter);
continue;

您正在访问无效的迭代器。

票数 3
EN

Stack Overflow用户

发布于 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.

  • Complexity:点或之后,析构函数使迭代器和引用失效T的析构函数的调用次数等于被擦除的元素的数量,但T的移动赋值运算符的调用次数等于被擦除的elements.

  • Throws:后向量中的元素的数量。除非T的复制构造函数、移动构造函数、赋值运算符或移动赋值运算符抛出异常,否则T的
  • 运算符将被调用。

但我很好奇:你为什么不直接使用remove/erase idiom?:

代码语言:javascript
复制
a.erase(std::remove(a.begin(), a.end(), 2), a.end());
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31758025

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档