如何使用boost :: range :: adapters :: transform over std :: unordered_set?

时间:2017-09-20 19:44:27

标签: c++ c++11 boost boost-range

我试图在std :: unordered_set上使用boost :: adapters ::但即使在非常小的实验中也会产生奇怪的行为。

我在Ubuntu 16.04上使用Boost 1.58.0和gcc 5.4.0。

在迭代范围时未列出范围初始化后添加的元素:

std::unordered_set<int> set = {0,1,2,3,4,5};

遵循与其他std容器(如std :: list)相同的方案按预期工作,加倍后者添加了元素。

如果使用以下方式初始化集合,则更奇怪:

{{1}}

范围迭代仅给出&#39; 10&#39;容器&#39; 10 0 1 2 3 4 5&#39;

有人能告诉我这个例子有什么问题吗?

2 个答案:

答案 0 :(得分:1)

transformed不会将范围的引用存储为范围;它在the range adaptor's construction时抓取范围的begin / end迭代器。

如果稍后在构造适配器后插入到集合中,则新元素可能不在插入之前由旧begin/end迭代器分隔的范围内。或者,更糟糕的是,如果触发重新哈希,插入将使所有迭代器无效。

答案 1 :(得分:0)

我无法真正看到问题:

Your exact sample code(现场)打印:

8 20 6 4 0 2 
4 10 3 2 0 1 

这似乎是你应该期待的。

Using the other elements

10 8 6 4 2 0 
5 4 3 2 1 0 

IDEA:

分配模板表达式可能是Undefined Behaviour

auto range = set | boost::adaptors::transformed(double_int());

由于double_int()可能会保留在transformed适配器 BY REFERENCE (尚未检查)。

看看这是否为您解决了问题:

for (auto i : set | boost::adaptors::transformed(double_int()))
    std::cout << i << " ";