编译时坐标生成
Coordinate generation at compile time
给定 hana::tuple
在编译时指定 N 维框的形状(例如 (2,3,2)
in 3D
),我想生成一个元组的元组编译时的所有坐标组合。
(0,0,0)
(0,0,1)
(0,1,0)
(0,1,1)
(0,2,0)
(0,2,1)
(1,0,0)
(1,0,1)
(1,1,0)
(1,1,1)
(1,2,0)
(1,2,1)
这个问题与我几天前发布的另一个问题 () 有关,但为 hana
重新表述。我似乎无法想出一种尊重 hana::tuple
对象不变性的算法。我无法识别 hana
算法的哪种组合将允许我生成递归调用并同时收集返回的元组。
根据您的评论,您只是想执行循环展开。你可能想用这两种方式来衡量,但通常当数组边界已知时,编译器在优化这些方面会比你做得更好。通过强制循环展开,您实际上可能会显着减慢或膨胀您的程序。
话虽这么说,如果那是你想做的,你可以按照以下方法去做:
#include <boost/hana.hpp>
namespace hana = boost::hana;
template <int ...> struct your_template { };
int main() {
auto xs = hana::to_tuple(hana::range_c<int, 0, 10>); // [0, ..., 9]
auto ys = hana::to_tuple(hana::range_c<int, 0, 10>); // [0, ..., 9]
auto zs = hana::to_tuple(hana::range_c<int, 0, 10>); // [0, ..., 9]
auto coords = hana::cartesian_product(hana::make_tuple(xs, ys, zs));
hana::for_each(coords, hana::fuse([](auto x, auto y, auto z) {
your_template<decltype(x)::value, decltype(y)::value, decltype(z)::value> foo;
(void)foo;
}));
}
但是请注意,生成笛卡尔积在编译时非常麻烦,因为您生成的是一个巨大的元组。以上,例如,在我的盒子上编译大约需要10s。
给定 hana::tuple
在编译时指定 N 维框的形状(例如 (2,3,2)
in 3D
),我想生成一个元组的元组编译时的所有坐标组合。
(0,0,0)
(0,0,1)
(0,1,0)
(0,1,1)
(0,2,0)
(0,2,1)
(1,0,0)
(1,0,1)
(1,1,0)
(1,1,1)
(1,2,0)
(1,2,1)
这个问题与我几天前发布的另一个问题 (hana
重新表述。我似乎无法想出一种尊重 hana::tuple
对象不变性的算法。我无法识别 hana
算法的哪种组合将允许我生成递归调用并同时收集返回的元组。
根据您的评论,您只是想执行循环展开。你可能想用这两种方式来衡量,但通常当数组边界已知时,编译器在优化这些方面会比你做得更好。通过强制循环展开,您实际上可能会显着减慢或膨胀您的程序。
话虽这么说,如果那是你想做的,你可以按照以下方法去做:
#include <boost/hana.hpp>
namespace hana = boost::hana;
template <int ...> struct your_template { };
int main() {
auto xs = hana::to_tuple(hana::range_c<int, 0, 10>); // [0, ..., 9]
auto ys = hana::to_tuple(hana::range_c<int, 0, 10>); // [0, ..., 9]
auto zs = hana::to_tuple(hana::range_c<int, 0, 10>); // [0, ..., 9]
auto coords = hana::cartesian_product(hana::make_tuple(xs, ys, zs));
hana::for_each(coords, hana::fuse([](auto x, auto y, auto z) {
your_template<decltype(x)::value, decltype(y)::value, decltype(z)::value> foo;
(void)foo;
}));
}
但是请注意,生成笛卡尔积在编译时非常麻烦,因为您生成的是一个巨大的元组。以上,例如,在我的盒子上编译大约需要10s。