从equal_range查询中筛选和修改 boost::multi_index 中的元素
Filter and modify elements in boost::multi_index from an equal_range query
我有一个hashed_non_unique
视图的boost::multi_index
。我想完成的是,在该视图中给定一个键,使用
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
并不像您似乎暗示的那样特殊,而只是与容器的第一个索引关联的迭代器。请注意,当myView
恰好是第一个索引时,这将与myIter
相同。- 尽管如此,哈希索引的迭代器不会因插入或修改而失效,因此您是安全的。事实上,您可以将
iters
定义为vector<myIter>
并直接存储迭代器,而无需任何进一步的转换 - 您仍然可以达到修改后不受潜在重新排序影响的预期效果。 - 即使您正在做的事情完全没问题,但如果您要挤压一些额外的性能,请注意,当键保持等效时,对散列索引中元素的修改不会更改基础顺序,因此在遍历等效键范围时,重新排序可能会影响您的唯一方式是当修改后的元素直接跳到范围之后(即, 就在
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;
}
我想我自己已经找到了答案。我们不是简单地修改 for 循环中的元素,而是需要先缓存元素,然后再修改它们以避免改变顺序。这里的诀窍是,不是将迭代器缓存到这个特定的视图,而是将迭代器缓存到元素本身,即
vector<BMIIter> iters;
for (myIter iter = iterRange.first; iter != iterRange.second; ++iter) {
if (filter(*iter)) {
iters.push_back(myBMI.iterator_to(*iter));
}
}
for (auto iter : iters) {
myBMI.modify(iter, modifier);
}
请注意,BMIIter
和myIter
是不同的迭代器类型 - 前者是元素本身的迭代器,而后者是特定于 myView 的迭代器。修改multi_index中的元素会使后者无效,但前者即使在重新排序后仍然有效。
相关文章:
- Mongodb c++驱动程序:如何查询元素的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 使用strcpy将char数组的元素复制到另一个数组
- 使用不带参数的函数访问结构元素
- 给定n个元素的m个集合.在C++中找到出现在最大集合数中的元素
- C++如何通过用户输入删除列表元素
- lower_bound()返回最后一个元素
- 基于多个条件处理地图中的所有元素
- 调整大小后指向元素值的指针unordered_map有效?
- 使用std::transform将一个范围的元素添加到另一个范围中
- 使用函数"remove"删除重复元素
- 具有最大子序列大小的序列,每个元素都相同
- 如何将两个不同矢量的同一位置的两个元素组合在一起
- 如何将元素添加到数组的线程安全函数?
- 有没有办法将谓词中的元素偏移量传递给 std 算法?
- 我想访问std::unique_ptr中的一个特定元素
- 如何通过 getter 函数删除矢量的元素?
- 向量元素的引用地址与它所指向的向量元素的地址不同.为什么
- 从控制台中删除最后打印的元素
- 擦除while循环中迭代的元素