首页 > 后端开发 > C++ > 正文

## std::vector::erase() 中擦除位置处的迭代器仍然有效吗?

Linda Hamilton
发布: 2024-10-28 12:21:31
原创
477 人浏览过

## Is the Iterator at the Erased Position in std::vector::erase() Still Valid?

理解 std::vector::erase() 中的迭代器失效

在本次讨论中,我们深入研究迭代器失效的主题:调用 std::vector::erase()。从之前的争论中可知,从向量中删除元素会使位于被删除元素之后的迭代器无效。然而,出现了一个问题:位于被擦除元素处的迭代器是否仍然被认为有效?

尽管我们直观地理解位于被擦除位置的迭代器应该保持可用,但精确的行为并不总是清晰的。为了说明这个概念,让我们分析以下从向量中删除所有奇数整数的代码片段:

<code class="cpp">typedef std::vector<int> vectype;
vectype vec;

for (int i = 0; i < 100; ++i) vec.push_back(i);

vectype::iterator it = vec.begin();
while (it != vec.end()) {
    if (*it % 2 == 1) vec.erase(it);
    else ++it;
}</code>
登录后复制

虽然此代码成功执行,但它违反了最佳实践。根据 C 标准,erase() 会使作为参数提供的迭代器处或之后的所有迭代器无效。在这种情况下,这意味着被擦除位置的迭代器变得无效。

但是,erase() 可以方便地返回一个新的迭代器,该迭代器指向紧随被擦除元素之后的元素,或者指向 vec.end () 如果不存在这样的元素。这个新的迭代器可以用来安全地恢复迭代。

需要注意的是,上述删除奇数元素的方法效率不高。每次删除一个元素时,后续元素都必须在向量中向左移动,从而导致复杂度为 O(n2)。使用擦除-删除惯用法可以更有效地完成此任务,该惯用法的运行时间为 O(n)。通过创建像 is_odd() 这样的谓词,我们可以优化擦除操作:

<code class="cpp">bool is_odd(int x) { return (x % 2) == 1; }
vec.erase(std::remove_if(vec.begin(), vec.end(), is_odd), vec.end());</code>
登录后复制

以上是## std::vector::erase() 中擦除位置处的迭代器仍然有效吗?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!