c++ - 如何在迭代时有效地替换 unordered_set 中的元素?

标签 c++ iterator replace unordered-set

假设你有一个

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));
  }
}

这可能会使 eraseinsert 处的迭代器无效(如果发生重新散列),因此该循环将表现出未定义的行为并且大多数可能会严重崩溃。

我能想到的一个解决方案是使用两个单独的 vector 来缓冲 inserterase 操作,然后使用重载采用迭代器对进行删除和插入(这可能对重新散列更友好)。

即使我使用缓冲区方法,这仍然看起来是臃肿的代码,并且可能导致两次可能都是不必要的重新散列。

那么,有没有更好的方法呢?

最佳答案

我只是想到了一种可能的方法(刚问完),但也许还有更好的方法。

将所有内容复制到 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/

相关文章:

c++ - 从 int 到 char* 的看似不正确的转换 - 如何查看问题

c++ - 无法复制到输出迭代器

Java:比较对象值

javascript正则表达式将所有重复的选项卡新行替换为单个新行

c++ - 从 dll 调用游戏功能时发生访问冲突

c++ - std::move() 与 priority_queue.top()

c++ - C++ 中的 double 字

python: filter() 可迭代,计算已过滤和未过滤的项目

search - 在 Vim 中删除/更改搜索到的文本

java - 替代连续 String.replace