【发布时间】:2020-05-24 05:48:49
【问题描述】:
我的代码如下所示:
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 实际上超出了保留容量,答案是否会改变,因此所有前向迭代器都将失效?
【问题讨论】:
-
std::unordered_set::reserve 与
std::vector::reserve做的事情不同。它不仅仅是分配空间。另外 -- 基于我做的几次运行, -- C++ 不能以这种方式工作,您可以通过几次运行来验证(或不验证)某些东西是安全的。它要么是未定义的行为,要么是已定义的行为,要么是实现定义的行为。 -
@J.Schultke 我想是这样,但我只是想确认我的理解是正确的。根据阅读 GManNickG 的回答,似乎即使我们保证不重新散列,我们仍然可以迭代新添加的元素?
-
@PaulMcKenzie 是的,我同意这两点。但是
std::unordered_set::reserve(N)会保证 unordered_set 至少可以存储N数字而无需重新散列对吗?如果没有冲突,它保证它可以准确存储N数字。
标签: c++ for-loop unordered-set