取自 range-v3 文档,以下示例演示了一个简单的views
流水线组合以生成range
:
std::vector<int> const vi{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
using namespace ranges;
auto rng = vi | views::remove_if([](int i){return i % 2 == 1;})
| views::transform([](int i){return std::to_string(i);});
我知道这views::foo
相当于类似的东西foo_view()
,因此上面的示例最终如下:
transform_view(remove_if_view(vi, <lambda>), <lambda>)
现在的问题是:
remove_if
和操作的顺序是如何transform
发生的?(我知道他们是懒惰的,他们实际上并没有在这一步计算,而不是稍后rng
具体化,但这不是重点)。
我可以在这里看到两个选项:
这些操作由 range-v3融合
rng
,当通过某个迭代器访问给定的元素时,这两个操作因此应用于该元素。当请求给定元素时,整个
remove_if
操作将被应用vi
,然后该操作的输出向量被馈送到transform
. 因此,我们最终得到了一个完整的“ trasformed + removed_if ”向量,它使我们能够访问所需的元素。
我很确定选项(1)是实际发生的事情。如果是这样的话,range-v3 是如何做到这一点的呢?它是否具有某种通用组合代码以组合无限数量的按视图组合操作?
附带问题:range-v3 视图公开了什么样的迭代器?我认为random-access
迭代器下方的任何内容都会使并行化变得不可能。
range-algorithms
元问题:如果选项(1)是事实,那么考虑到它们将一个简单的范围(由多个视图组成,通过操作融合按需计算)作为输入,并行化不是非常简单吗?