繁体   English   中英

将范围的范围连接到范围

[英]Concatenate range of ranges to range

rw = ranges::views

我正在尝试专门使用range-v3创建一个类似的构造:

std::vector<int> v;

// range = {0, 1, 2}
auto range = rw::ints (0, 3);

for (int i : range)
    for (int j : range)
        v.push_back (func (i, j))

// v = {func (0, 0), func (0, 1), func (0, 2),
//      func (1, 0), func (1, 1), func (1, 2),
//      func (2, 0), func (2, 1), func (2, 2)}

我尝试了以下选项:

// range = {0, 1, 2}
auto range = rw::ints (0, 3);

// range_of_ranges = {{func (0, 0), func (0, 1), func (0, 2)},
//                    {func (1, 0), func (1, 1), func (1, 2)},
//                    {func (2, 0), func (2, 1), func (2, 2)}}
auto range_of_ranges = rw::transform (range, [] (int i) {
    return rw::transform (range, [i] (int j) { return func (i, j); });
});

// result = {func (0, 0), func (0, 1), func (0, 2),
//           func (1, 0), func (1, 1), func (1, 2),
//           func (2, 0), func (2, 1), func (2, 2)}
auto result = rw::concat (range, range, range);

for (auto x : result)
    printf ("%d\n", x);

但如果我更换

// result = {func (0, 0), func (0, 1), func (0, 2),
//           func (1, 0), func (1, 1), func (1, 2),
//           func (2, 0), func (2, 1), func (2, 2)}
auto result = rw::concat (range, range, range);

// result = { {{func (0, 0), func (0, 1), func (0, 2)},
//             {func (1, 0), func (1, 1), func (1, 2)},
//             {func (2, 0), func (2, 1), func (2, 2)}} }
auto result = rw::concat (range_of_ranges);

会有一个编译器警告:

warning: format specifies type 'int' but the argument has type 'ranges::iota_view<int, int>' [-Wformat]
    printf ("%d\n", x);

不幸的是,它不起作用,我真的不明白如何正确修复它。 我知道 concat function 应该采用它的 arguments 并将它们组合成一个范围,我刚刚创建了一个长度为 1 的范围,但我不知道哪种解决方案是正确的。 你能给我一个提示吗?

UPD[1](基于Jarod42评论: range-v3 has views::cartesian_product :结果将代码简化为以下内容:

auto range = rw::ints (0, 3);

auto cart_prod = rw::cartesian_product (range, range);

auto unpack_args_and_call_func = [] (const auto &arg) {
    return std::apply (func, arg);
};

auto result = rw::transform (cart_prod, unpack_args_and_call_func);

但是,使用 unpacking 参数看起来不是很好和方便。

UPD[2](基于Jarod42评论:还有views::join for your range_of_ranges :替换

// result = {func (0, 0), func (0, 1), func (0, 2),
//           func (1, 0), func (1, 1), func (1, 2),
//           func (2, 0), func (2, 1), func (2, 2)}
auto result = rw::concat (range, range, range);

// result = { {{func (0, 0), func (0, 1), func (0, 2)},
//             {func (1, 0), func (1, 1), func (1, 2)},
//             {func (2, 0), func (2, 1), func (2, 2)}} }
auto result = rw::join (range_of_ranges);

感谢Jarod42

// range = {0, 1, 2}
auto range = rw::ints (0, 3);

// range_of_ranges = {{func (0, 0), func (0, 1), func (0, 2)},
//                    {func (1, 0), func (1, 1), func (1, 2)},
//                    {func (2, 0), func (2, 1), func (2, 2)}}
auto range_of_ranges = rw::transform (range, [] (int i) {
    return rw::transform (range, [i] (int j) { return func (i, j); });
});

// result = {func (0, 0), func (0, 1), func (0, 2),
//           func (1, 0), func (1, 1), func (1, 2),
//           func (2, 0), func (2, 1), func (2, 2)}
auto result = rw::join (range_of_ranges);

for (auto x : result)
    printf ("%d\n", x);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM