假设我有一系列名为rng的T.我可以
auto groups = ranges::view::group_by(rng, bin_op);
Run Code Online (Sandbox Code Playgroud)
群体现在是T的范围.
我也可以这样做
auto groups = ranges::view::group_by(rng, bin_op) | ranges::to_vector;
Run Code Online (Sandbox Code Playgroud)
得到T的范围向量.不过这个
auto groups = ranges::view::group_by(rng, bin_op)
| ranges::to_vector
| ranges::action::transform([] (auto r) { return r | ranges::to_vector; };
Run Code Online (Sandbox Code Playgroud)
以及
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; };
Run Code Online (Sandbox Code Playgroud)
因为看起来range :: action :: transform()在这种情况下返回void并且"传递给action :: transform的函数的结果类型必须可写回源范围",因此不起作用.
那么如何将范围范围转换为矢量矢量?
注意:对不好的标签很抱歉,但我找不到范围/ range-ts/ranges-v3标签,我不允许创建一个标签,也不能在标题中使用它.
您只需将结果分配给a vector<vector<T>>,就会发生正确的事情.例如:
#include <vector>
#include <iostream>
#include <range/v3/core.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;
});
std::vector<std::vector<int>> vs = groups; // WORKS
// Display the result: [[0,1,2],[3,4,5],[6,7,8],[9]]
std::cout << ranges::view::transform(vs, ranges::view::all) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
假设您使用的是 Rangesv3,我对文档的阅读给了我这样的信息:
auto groups = ranges::view::group_by(rng, bin_op)
| ranges::view::transform( ranges::to_vector )
| ranges::to_vector;
Run Code Online (Sandbox Code Playgroud)
或者可能
auto groups = ranges::view::group_by(rng, bin_op)
| ranges::view::transform( [] (auto r) { return r | ranges::to_vector; } )
| ranges::to_vector;
Run Code Online (Sandbox Code Playgroud)
(我记得ranges::to_vector可以以函数风格的方式使用,但我可能是错的,或者事情可能已经改变。第一个假设可以;第二个则不然。)
它的作用是首先将范围的惰性范围转换为向量的惰性范围。
然后它将向量的惰性范围转换为向量的向量。
这效果更好(从内到外),因为中间产品“在外面”是惰性的。可能有一种方法可以从外到内做到这一点,但是惰性范围向量必须以惰性范围向量不存在的方式实际存在。