【问题标题】:Is order of iteration over the elements of std::unordered_set guaranteed to be always the same?std::unordered_set 的元素的迭代顺序是否保证始终相同?
【发布时间】:2016-07-14 12:25:33
【问题描述】:

如果多次迭代std::unordered_set 的元素而不改变集合的内容(但可能从中读取,计算其大小等),是否保证每个元素将以相同的顺序访问时间?

【问题讨论】:

  • 我知道这不一样但它是相关的:stackoverflow.com/questions/14346361/…
  • 它在名称中显示“无序”。
  • @n.m.你误解了我的问题。我不是在问订单是否可以预测,而是在问它是否稳定。
  • @NicolBolas 所以答案是否定的? C++ 规范中是否有一个条目说,如果没有没有任何价值的尖刻 cmets,就无法回答像我这样的问题?
  • 附言。 “为什么规范会保证实际未定义的东西的稳定性?” - 它实际上经常这样做。

标签: c++ c++11 iteration unordered-set


【解决方案1】:

在你提到的具体情况下,是的。因为该标准明确说明了何时进行重新散列(并因此重新排序)。

它只发生在插入过程中。

§ 23.2.5 [unord.req]

9 无序关联容器的元素被组织成桶。具有相同哈希的键 代码出现在同一个桶中。随着元素的添加,桶的数量会自动增加 到一个无序的关联容器,以便每个桶的平均元素数保持在以下 一个界限。重新散列使迭代器无效,更改元素之间的顺序以及更改哪些存储桶 元素出现,但不会使指向元素的指针或引用无效。对于 unordered_multiset 和 unordered_multimap 一样,重新散列保留了等效元素的相对顺序。

【讨论】:

  • 谢谢,一个真正知道他在说什么的人的回答很好:)
  • @quant_dev 需要注意的一件事是在erase 期间,仅保证从 c++14 开始保留订单。在 c++11 中,您无法在 for 循环中可移植地擦除项目,因为每次擦除都有可能重新排序地图。如果您使用的是 c++11(并且无法升级),请改用 erase_if,并记住地图可能因此被重新排序。
  • 我不需要擦除。谢谢。
  • @RichardHodges 你的意思是remove_if
猜你喜欢
  • 2021-10-21
  • 2020-11-23
  • 1970-01-01
  • 2011-09-29
  • 2015-04-21
  • 2011-11-30
  • 2019-03-17
  • 2012-12-19
相关资源
最近更新 更多