2016-08-02 7 views
1

コンパイル時にN次元ボックスの形状を指定すると(例えば、(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) コンパイル時の座標生成

質問は、私は数日前に掲示別の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秒かかります。

関連する問題