将范围的范围连接到范围
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 函数应该接受它的参数并将它们组合成一个范围,我只是创建了一个长度为 1 的范围,但我不知道哪个解决方案是正确的。你能给我一个提示吗?
UPD[1](基于 Jarod42 评论:range-v3
有 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);
但是,使用解包参数看起来不太好和不方便。
UPD[2](基于 Jarod42 评论:您的 range_of_ranges
也有 views::join
):
替换
// 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);
让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 函数应该接受它的参数并将它们组合成一个范围,我只是创建了一个长度为 1 的范围,但我不知道哪个解决方案是正确的。你能给我一个提示吗?
UPD[1](基于 Jarod42 评论:range-v3
有 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);
但是,使用解包参数看起来不太好和不方便。
UPD[2](基于 Jarod42 评论:您的 range_of_ranges
也有 views::join
):
替换
// 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);