向量向量的范围范围

ranges of ranges to vector of vectors

本文关键字:向量 范围      更新时间:2023-10-16

假设我有一系列名为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; };

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

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

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

您可以使用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 日:以前,此答案建议简单地将groups分配给vector<vector<int>>变量,因为 range-v3 用于支持从视图到容器的隐式转换。隐式转换是有问题的,因此它们被丢弃了。ranges::to现在是这样做的惯用方法。

假设您使用的是 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可以以函数式的方式使用,但我可能是错的,或者事情可能会改变。 第一个假设它可以;第二个没有。

这样做的作用是首先将惰性范围转换为向量延迟范围。

然后,它将向量的延迟范围转换为向量的向量。

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