首页 > 解决方案 > 迭代期间添加到 std::unordered_set(或 unordered_map)中的元素是否会在迭代期间被访问?

问题描述

我的代码如下所示:

std::unordered_set<int> ht{1,2,3};
ht.reserve(10000);  // ht will not exceed this size

for(int i = 0; i < n; i++)
{ 
  auto j = i;
  for(auto it = ht.begin(); it != ht.end(); ++it)
  {
    // do some stuff
    int v = j++;
    ht.emplace(v);
  }
}

对于内部循环,我想从 ht 的开头循环到结尾,但我不希望循环遍历循环中任何新添加的元素。换句话说,上面是否等同于下面?

std::unordered_set<int> ht{1,2,3};
ht.reserve(10000);  // ht will not exceed this size

for(int i = 0; i < n; i++)
{
  auto temp = ht;
  auto j = i;
  for(auto it = ht.begin(); it != ht.end(); ++it)
  {
    // do some stuff
    auto v = j++;
    temp.emplace(j);
  }

  ht = temp;
}

基于我所做的一些运行,它似乎是等效的,但我不知道这是否是未定义的行为,或者它们是否确实是等效的。如果将unordered_set更改为 a vector,这将不起作用,但似乎前向迭代器工作。

ht.reserve(10000); // ht will not exceed this size如果不存在或实际上超过了保留容量,答案是否会改变ht,因此所有前向迭代器都将失效?

标签: c++for-loopunordered-set

解决方案


不,这不安全:

在大多数情况下,容器中的所有迭代器在插入后仍然有效。唯一的例外是当容器的增长迫使重新散列时。在这种情况下,容器中的所有迭代器都将失效。

有时它有效,但我认为这对你来说还不够!


推荐阅读