我有一个 boost::multi_index
和一个 hashed_non_unique
View 。我想要完成的是,给定该 View 中的键,使用
pair<myIter, myIter> iterRange = myView.equal_range(key);
for (myIter iter = iterRange.first; iter != iterRange.second; ++iter) {
// ...
}
查找与该键关联的所有元素。然后,通过过滤器运行这些元素
bool filter(Element e) { /* some filtering logic*/ }
并用修饰符修改过滤后的结果
void modifier(Element e) { /* modify the elements with e.g. myView.modify() */ }
但是,简单地将这些部分放在一起是行不通的,因为修改元素会导致 multi_index 重新排序,这会使我的 iterRange 无效。
执行此操作的正确方法是什么?谢谢!
最佳答案
对您提出的解决方案的一些评论:
-
BMIter
并不像您暗示的那样特别,而只是与容器的第一个索引相关联的迭代器。请注意,这与myIter
相同什么时候myView
恰好是第一个索引。 - 尽管如此,散列索引的迭代器 are not invalidated by insertions or modifications ,所以你很安全。事实上,您可以定义
iters
作为vector<myIter>
并直接存储迭代器而不进行任何进一步的转换——您仍然实现了预期效果,即在修改后不受潜在重新排序的影响。 - 即使您所做的一切都很好,但如果您要压缩一些额外的性能,请注意修改散列索引中的元素 does not change the underlying ordering when the key remains equivalent ,因此在遍历等效键范围时,重新排序可能影响您的唯一方式是当修改后的元素直接跳转到范围之后(即,恰好在
iterRange.second
之前)。有了这个想法,你就可以省下iters
了技巧如下:
for (myIter iter = iterRange.first; iter != iterRange.second; ) {
auto nextIter = std::next(iter);
if (filter(*iter)) {
myView.modify(iter, modifier);
if (nextIter != iterRange.second && std::next(iter) == iterRange.second)
iterRange.second = iter;
}
iter = nextIter;
}
关于c++ - 从 equal_range 查询过滤和修改 boost::multi_index 中的元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55820467/