会在迭代过程中访问在迭代过程中添加到std :: unordered_set(或unordered_map)中的元素吗?

问题描述 投票:1回答:2

我有如下代码:

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更改为vector,这将不起作用,但似乎前向迭代器可以工作。

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

c++ for-loop unordered-set
2个回答
1
投票

不,这不安全:

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

有时可以,但是我认为这对您来说还不够!


1
投票

没有参见cppreference on std::unordered_set

Cppreference.com的“迭代器无效”部分描述了何时使迭代器无效。如果使用std::unordered_set,则在进行重新哈希处理时插入是不安全的。

仅当新的元素数大于std::unordered_set时才进行哈希处理>

而且您不确定是否插入元素会导致这种情况发生。

在您的示例中,您实际上并未取消引用迭代器,所以为什么不循环遍历集合的大小?

max_load_factor()*bucket_count()
© www.soinside.com 2019 - 2024. All rights reserved.