gpt4 book ai didi

C++: boost 指向错误元素的范围迭代器

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:26:19 25 4
gpt4 key购买 nike

我遇到了一个奇怪的问题。我有一个 vector<pair<bool, int>>我只需要从中读取(也可能写入)对的 bool 值为真的 vector 元素。我正在使用 boost 范围过滤器和反向适配器来做到这一点。

但是,我注意到适配器的顺序,即我是否使用反向 |过滤或过滤 |反转产生不同的结果。事实上,当我使用 filtered |反转然后当我使用迭代器到转换范围来更改对的 bool 值时,更改后的迭代器指向不同的 vector 元素。当我使用 reversed | 时不会发生这种情况过滤。下面是演示该问题的代码。非常感谢任何关于为什么会发生这种情况的想法!

#include <boost/range/adaptors.hpp>
#include <vector>
#include <utility>
#include <iostream>

using namespace boost::adaptors;

using container_type = std::vector<std::pair<bool,int>>;

struct to_include {
bool operator()(const std::pair<bool,int>& x) {
return x.first;
}
};

int main() {
container_type container;

/* element0: 1, 1 */
/* element1: 1, 2 */
/* element2: 1, 3 */
for(size_t i=0; i!=3; ++i) container.push_back(std::make_pair(true, i+1));
container_type container_cpy = container;

/* filter and then reverse */
auto fr = container | filtered(to_include()) | reversed;
auto fr_it1 = fr.begin();
auto fr_it2 = std::next(fr_it1);
fr_it2->first = false;

std::cout << "FILTER AND THEN REVERSE\n";
std::cout << fr_it2->first << " " << fr_it2->second << '\n'; /* prints (1,1) instead of (0,2) */

/* reverse and then filter */
auto rf = container_cpy | reversed | filtered(to_include());
auto rf_it1 = rf.begin();
auto rf_it2 = std::next(rf_it1);
rf_it2->first = false;

std::cout << "\nREVERSE AND THEN FILTER\n";
std::cout << rf_it2->first << " " << rf_it2->second << '\n'; /* prints (0,2) */

return 0;
}

最佳答案

这是一个微妙的问题。这里的要点是,在你修改了fr_it2指向的元素之后,你也隐含地修改了fr_it1,因为fr是一个惰性 View 在原始范围内。这意味着需要重新计算 transformed 过滤器。这是一个非常不直观的属性,因为对于热切的 STL 范围,通过迭代器进行的修改不会修改迭代器本身,但对于惰性范围,这不再是真的!

事实上,如果您使用“新鲜”迭代器打印整个 frrf 范围,您会发现它们的内容实际上是相同的。

fr_it2->first = false;
for (auto e : fr) std::cout << e.first << e.second << ";"; // prints 13;11
...
rf_it2->first = false;
for (auto e : rf) std::cout << e.first << e.second << ";"; // prints 13;11

Live Example 1 .所以实际上中间的元素确实被删除了!

我认为您不应该通过迭代器将元素修改到适应范围内,而是通过迭代器将元素修改到您的主容器中,如下所示:

auto fr_it1 = container.begin();
...
auto rf_it1 = container_cpy.begin();

Live Example 2 .如果这样做,您将获得一致的结果,两种方法都显示“0 2”。

关于C++: boost 指向错误元素的范围迭代器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18893697/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com