8

假设我有一个称为 rng 的 T 范围。我可以

auto groups = ranges::view::group_by(rng, bin_op);

组现在是一系列 T 的范围。

我也可以这样做

auto groups = ranges::view::group_by(rng, bin_op) | ranges::to_vector;

得到 T 范围的向量。然而这

auto groups = ranges::view::group_by(rng, bin_op)
            | ranges::to_vector
            | ranges::action::transform([] (auto r) { return r | ranges::to_vector; };

auto groups = ranges::view::group_by(rng, bin_op)
            | ranges::to_vector
            | ranges::action::transform([] (auto r) { return std::vector<T>{} | ranges::action::push_back; };

将不起作用,因为在这种情况下,ranges::action::transform() 显然返回 void 并且“传递给 action::transform 的函数的结果类型必须可写回源范围”。

那么如何将我的范围范围转换为向量的向量呢?

注意:抱歉标签不好,但我找不到 range/ranges-ts/ranges-v3 标签,我不能创建一个标签,也不能在标题中使用它。

4

2 回答 2

9

您可以使用ranges::to将范围的范围转换为向量的向量。例如:

#include <vector>
#include <iostream>
#include <range/v3/range/conversion.hpp>
#include <range/v3/view/all.hpp>
#include <range/v3/view/group_by.hpp>
#include <range/v3/view/transform.hpp>

int main() {
    std::vector<int> rng {0,1,2,3,4,5,6,7,8,9};
    auto groups = ranges::view::group_by(rng, [](int i, int j){
        return j/3 == i/3;
    });

    auto vs = groups | ranges::to<std::vector<std::vector<int>>>;

    // Display the result: [[0,1,2],[3,4,5],[6,7,8],[9]]
    std::cout << ranges::view::transform(vs, ranges::view::all) << std::endl;
}

2020 年 6 月 10 日:以前,此答案建议简单地将 from 分配groupsvector<vector<int>>变量,因为 range-v3 用于支持从视图到容器的隐式转换。隐式转换是有问题的,因此它们被删除了。ranges::to现在是执行此操作的惯用方式。

于 2017-07-20T17:29:22.250 回答
3

假设您使用的是 Rangesv3,我对文档的阅读给了我这样的信息:

auto groups = ranges::view::group_by(rng, bin_op)
        | ranges::view::transform( ranges::to_vector )
        | ranges::to_vector;

或者可能

auto groups = ranges::view::group_by(rng, bin_op)
        | ranges::view::transform( [] (auto r) { return r | ranges::to_vector; } )
        | ranges::to_vector;

(我记得ranges::to_vector可以以函数式的方式使用它,但我可能是错的,或者事情可能已经改变。第一个假设它可以;第二个没有。)

它的作用是首先将惰性范围转换为惰性向量范围。

然后它将向量的惰性范围转换为向量的向量。

这效果更好(由内而外),因为中间产品“在外面”是懒惰的。可能有一种从外到内的方法,但是惰性范围向量必须以惰性向量范围不存在的方式实际存在

于 2017-07-20T11:18:47.403 回答