假设你有一个
std::unordered_set<std::shared_ptr<A>> as;
// (there is an std::hash<std::shared_ptr<A>> specialisation)
并且您想在遍历它时替换它的一些元素:
for (auto it = as.begin(); it != as.end(); ++it) {
if ((*it)->condition()) {
as.erase(it);
as.insert(std::make_shared<A>(**it));
}
}
这可能会使 erase
和 insert
处的迭代器无效(如果发生重新散列),因此该循环将表现出未定义的行为并且大多数可能会严重崩溃。
我能想到的一个解决方案是使用两个单独的 vector
来缓冲 insert
和 erase
操作,然后使用重载采用迭代器对进行删除和插入(这可能对重新散列更友好)。
即使我使用缓冲区方法,这仍然看起来是臃肿的代码,并且可能导致两次可能都是不必要的重新散列。
那么,有没有更好的方法呢?
最佳答案
我只是想到了一种可能的方法(刚问完),但也许还有更好的方法。
将所有内容复制到 vector ,然后从 vector 重建集应该更快:
std::vector<std::shared_ptr> buffer;
buffer.reserve(as.size());
for (auto it = as.begin(); it != as.end(); ++it) {
if ((*it)->condition()) {
buffer.push_back(std::make_shared<A>(**it));
} else {
buffer.push_back(*it);
}
}
as = std::unordered_set<std::shared_ptr<A>>(buffer.begin(),buffer.end());
关于c++ - 如何在迭代时有效地替换 unordered_set 中的元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12661023/