【发布时间】:2014-09-22 17:02:17
【问题描述】:
考虑在迭代时从关联容器中删除元素的规范算法:
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 的文档后,我在阅读了以下注释后有点担心:
保留未擦除元素的顺序(这使得在遍历容器时可以擦除单个元素)(C++14 起)
基于此声明,我假设 C++14 标准中添加了语言,以确保库实现者在调用 std::unordered_map::erase 后保证排序。例如,也许这样的要求会限制实现在删除元素后不重新散列整个容器,而是只允许它从相应的桶中删除元素?
如果在 C++11 中没有这样的保证,并且如果我希望我的代码是可移植的,我是否必须担心如果我从 std::unordered_map 中删除一个元素,某些元素会被多次访问或根本不被访问在迭代期间?
【问题讨论】:
-
参考引用 C++11 规则的this answer。对于从无序关联容器中擦除,只有被擦除元素的迭代器是无效的。所以你的代码是有效的。
-
@Praetorian:感谢您的澄清。我知道迭代器在擦除后仍然有效,但我担心的是,鉴于上面的 C++14 保证,将继续迭代直到最后产生相同的元素序列,就好像我没有删除元素一样?如果是这样,您知道为什么委员会认为有必要在 C++14 中添加上述说明吗?
-
对不起,我误解了你的问题。 Here's 导致措辞变化的问题。我认为您的问题的答案是 - 标准 pre-C++14 不保证,在实践中保证。链接的报告也说明了这一点 - 无论如何,任何实际的实现都不会这样做。我会重新打开这个问题,也许有人会为你提供更好的答案。
-
@Praetorian:你对一个好问题有一个很好的答案。请把它放在我可以投票的地方。 :-)
-
@Howard 谢谢你,但我希望像你这样对至少一个标准库实现有深入了解的人会发布答案。无论如何,现在已经有一个答案说明了我在评论中所做的事情。
标签: c++ c++11 stl iterator unordered-map