C++11:迭代时从 std::unordered_map 中删除单个元素是否安全?

标签 c++ c++11 stl iterator unordered-map

考虑在迭代时从关联容器中删除元素的规范算法:

for (auto iter = myMap.begin(); iter != myMap.end(); )
{
    if (/* removal condition */)
    {
        iter = myMap.erase(iter);
    }
    else
    {
        ++iter;
    }
}

在使用 C++11 std::unordered_map 容器时,我一直在应用这个算法,没有多加考虑。但是,在浏览 cppreference.com 上的 std::unordered_map::erase 文档后,看了下面的说明,我有点担心了:

The order of the elements that are not erased is preserved (this makes it possible to erase individual elements while iterating through the container) (since C++14)

基于此声明,我假设 C++14 标准中添加了语言,以确保库实现者在调用 std::unordered_map::erase 后保证排序。例如,也许这样的要求会限制实现在删除元素后不重新散列整个容器,而是只允许它从相应的桶中删除元素?

如果在 C++11 中没有这样的保证,并且如果我希望我的代码是可移植的,我是否必须担心如果我从 中删除一个元素,某些元素会被多次访问或根本不被访问std::unordered_map 在迭代期间?

最佳答案

编辑:NoScript 的危险。 我运行了 noscript,它将 C11 和 C14 选项卡显示为一个框。 Praetorian 的回答是正确的,它在实践中得到保证,并在 c14 中正式化。

** 由于没有脚本,以下是错误的。

在 cplusplus 的底部指出

Only the iterators and references to the elements removed are invalidated.

The rest are unaffected.

The relative order of iteration of the elements not removed by the operation is preserved.

http://www.cplusplus.com/reference/unordered_map/unordered_map/erase/

在页面顶部,它声明它适用于 C++11...所以除非他们为 C++14 更新它,否则我认为它也适用于 C++11。 Praetorian 应该给出答案,你应该检查他的答案,因为即使在 C++11 的标准中没有保证(C++14 是这类事情的补丁),它在实践中是有保证的。

我找不到 STL 标准,我似乎放错了位置,或者我会去看看是否有保证我可以指出的文本。 :-/

关于C++11:迭代时从 std::unordered_map 中删除单个元素是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25047241/

相关文章:

c++ - 为非 STL 容器创建我自己的迭代器

c++ - 为什么将 std::auto_ptr<> 与标准容器一起使用是错误的?

c++ - 有没有办法增加数组的内存?和相关问题

c++ - 是否有可能有一个非递归的 at_c 实现?

c++ - 如何在 C++ 中创建一个方法的多个版本?

c++ - 为什么以及如何额外的括号改变 C++ (C++11) 中表达式的类型?

c++ - 基于范围的 for 和其他增量

c++ - 尝试在 C++ 中删除矩阵的一部分时获取 glibc 检测到错误

c++ - Visual C++ 2010 是否支持 C++11 线程库?

c++ - STL 不提供通过索引返回迭代器的函数有什么原因吗?