std::unordered_set
的值不可变,因为它们都是键和值。如果首先删除,修改然后重新插入其元素,修改std::unordered_set
元素的正确方法是什么? erase
不会使任何迭代器失效,但insert
可能会失效。显而易见的答案是使用迭代器,erase
返回。我想,有一种方法可以解决这个问题,即在成功插入之后将循环迭代器重置为unordered_set
的开头。我想确定,这是唯一的方法。
答案 0 :(得分:2)
erase
不会使任何迭代器无效,但insert
可能会失效。
您可以随时检查insert
是否会这样做:
如果由于插入而发生重新散列,则所有迭代器都是 无效。否则迭代器不会受到影响。参考文献不是 无效。仅当新元素数量为时,才会发生重新散列 等于或大于
max_load_factor()*bucket_count()
。 (来自cppreference)
所以,如果你注意重复,你的方法可行。当然,当您检测到重新发送将发生时,它会让您知道该怎么做。
您可以通过在循环之前增加集合的容量来降低重新散列的概率。
处理重组的最简单方法是重新开始后重新开始。也许还有其他方法可以处理它,但我不会冒险。
说完所有这些之后,你在这里描述的似乎表明你可能需要另一个容器。如果unordered_set
确实是您应用程序的最佳容器,我很可能仍然使用Martin's solution,即使用中间容器。它不那么凌乱,我可以看到发生了什么;我可以推断正确性。
答案 1 :(得分:1)
我认为你最好使用中间容器,比如:
unordered_set<int> original;
...
vector<int> temporary;
for (auto it = original.begin(), itEnd = original.end(); it != itEnd; ) {
if (...) {
int newValue = ...;
auto toDelete = it++;
original.erase(toDelete);
temporary.push_back(newValue);
} else {
...
++it;
}
}
original.insert(temporary.begin(), end.begin());
答案 2 :(得分:1)
使用临时unordered_set
,您将填充第一个(带有提示),然后将原始集与临时交换。