2016-08-02 75 views
1

在编译时指定一个指定N维框的形状的hana::tuple(例如(2,3,2),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) 在编译时生成坐标

问题是关系到另外一个我张贴在几天前(link),但对于重新hana。我似乎很难提出一个尊重hana::tuple对象的不变性的算法。我没有认识到hana算法的组合会让我产生一个递归调用,并且同时收集返回的元组。

+1

你是否需要自己的坐标在编译时可用(例如用它们实例化一个模板)?你想达到什么目的?如果你只是想优化一个循环,不要。在正常循环中使用'std :: array',优化器将完成它的工作。否则,使用'hana :: cartesian_product'。 –

+0

我需要编译时的坐标来实例化一个模板。但是模板只是需要的,因为我正在做你猜到的 - 手动展开嵌套循环。起初我使用'std :: array'实现了我的算法。但是我不确定我应该相信编译器。这就是为什么我试图使用元编程实现另一个版本,并检查是否有任何显着的性能优势。 –

回答

1

根据您的评论,您只是试图执行循环展开。你可能想要测量两种方式,但通常情况下,编译器在你知道数组边界时优化这些东西的工作要比你做得更好。通过强制循环展开,实际上可能会显着减慢或膨胀程序。

话虽这么说,如果这是你想做的事,这里是你如何能做到这一点:

#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; 
    })); 
} 

注意,但是,产生笛卡尔乘积是在编译时非常讨厌的,因为你正在产生一个巨大的元组。例如,上面的内容大约需要10秒才能在我的盒子上编译。