【问题标题】:Does repeated iteration through an unordered_set produce consistent results?通过 unordered_set 重复迭代会产生一致的结果吗?
【发布时间】:2018-11-14 00:16:40
【问题描述】:

假设我有一个unordered_set<int> S

我知道我可以通过以下方式遍历 S:

void iterate(){
    for (const auto& elem: S) {
        cout<<elem<<endl;
    }
}

我的问题是:如果我调用 iterate() 并打印出特定的数字序列,是否可以保证如果我调用 iterate() 的次数不限,它总是会打印出相同的序列?

【问题讨论】:

  • 我认为应该是一样的,虽然我在标准中找不到拼写的地方

标签: c++ unordered-set


【解决方案1】:

可以,只要S 没有被修改。 [container.requirements.general]p6:

begin() 返回一个引用容器中第一个元素的迭代器。

使用定冠词“the”意味着只有一个这样的“第一要素”。因此,在同一个(未更改的)容器上多次调用 begin() 必须返回引用同一个元素的迭代器。

此外,所有容器迭代器都必须至少是前向迭代器(参见同一子条款中的表 64)。

其余部分不符合 [forward.iterators] 中的前向迭代器要求,特别是:

  • 两个可取消引用的迭代器比较相等当且仅当取消引用它们的结果绑定到同一个对象;和
  • 递增两个相等的迭代器会产生相等的迭代器。

由于你从相等的迭代器开始,迭代的每一步都必须产生相等的迭代器,它必须引用容器中的相同元素。

【讨论】:

  • 也许DS9000 可以检测到永远不会同时存在两个这样的迭代器(我们在问题中开始...结束,然后开始...结束)并给出不同的顺序第二次,实际上没有违反任何规则
【解决方案2】:

如果你不改变集合的内容,你会在迭代过程中得到相同的元素顺序。

这是因为迭代是确定性的。如果集合的内部结构无故改变,迭代器就会失效。

【讨论】:

  • 从标准的角度来看,这种保证可能很弱,但任何合理的实现都可以保证这一点。毕竟,unordered_set 的状态不会因为调用 begin() 和 end() 而改变。
【解决方案3】:

我发现了一个句子“注意 unordered_set 对象不保证哪个特定元素被认为是它的第一个元素。”在 this 网站我相信这可以帮助您解决问题。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-08-18
    • 1970-01-01
    • 2021-07-15
    • 2022-10-14
    • 1970-01-01
    • 2012-01-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多