現在、boost::fusion::for_each は単一のシーケンスの要素を繰り返します。同様の方法で機能する関数を作成しようとしていますが、多くのシーケンスがあり、シーケンス間のすべての可能な組み合わせを反復処理します。
たとえば、S1、S2、S3 の 3 つのシーケンスがある場合、このようなファンクターを作成したいと思います
struct my_functor {
template <class x, class y, class z>
void operator()(x& el1, y& el2, z& el3) {...}
}
そして電話する
for_each(s1, s2, s3, my_functor()) // applies the functor to all combinations of elements of s1, s2, s3
ここで、s1、s2、s3 は S1、S2、S3 のインスタンスです。
一般的なケース (任意の数のシーケンス) のコードを書くことから始めましたが、難しすぎることがわかりました。そこで、2 つのシーケンスだけから始めて、そこから取得することにしました。次のような 2 つのシーケンス (簡単にするために fusion::vectors を想定) がある場合に、なんとかやり遂げることができました。
//for_each.hpp
#include <boost/fusion/include/mpl.hpp>
#include <boost/fusion/include/at_c.hpp>
#include <boost/fusion/include/vector.hpp>
#include <boost/fusion/include/back.hpp>
#include <boost/mpl/size.hpp>
template <class Seq1, class Seq2, int i1, int i2, class F>
struct my_call {
static void apply(Seq1& seq1, Seq2& seq2, F& f) {
f(boost::fusion::at_c<i1>(seq1), boost::fusion::at_c<i2>(seq2)); // apply functor for a given pair of ints
my_call<Seq1, Seq2, i1, i2+1, F>::apply(seq1, seq2, f); // increase second int by 1 and apply functor again
}
};
// terminal condition for 2nd sequence
template <class Seq1, class Seq2, int i1, class F>
struct my_call<Seq1, Seq2, i1, boost::mpl::size<Seq2>::type::value - 1, F> {
static void apply(Seq1& seq1, Seq2& seq2, F& f) {
f(boost::fusion::at_c<i1>(seq1), boost::fusion::back(seq2));
my_call<Seq1, Seq2, i1+1, 0, F>::apply(seq1, seq2, f); // reset 2nd int and increase 1st by 1
}
};
// terminal condition for both sequences
template <class Seq1, class Seq2, class F>
struct my_call<Seq1, Seq2, boost::mpl::size<Seq2>::type::value - 1, boost::mpl::size<Seq2>::type::value - 1, F> {
static void apply(Seq1& seq1, Seq2& seq2, F& f) {
f(boost::fusion::back(seq1), boost::fusion::back(seq2));
}
};
// the actual function
template <class Seq1, class Seq2, class F>
void for_each(Seq1& seq1, Seq2& seq2, F& f) {
my_call<Seq1, Seq2, 0, 0, F>::apply(seq1, seq2, f);
}
そしてメインとして
//main.cpp
#include "for_each.hpp"
#include <iostream>
struct myf {
template <class X, class Y>
void operator()(X& x, Y& y) {
std::cout << x + y << std::endl;
}
};
int main() {
boost::fusion::vector<int, double> x(1, 2.5);
boost::fusion::vector<double, int> y(2, 5);
myf F;
for_each(x, y, F);
return 0;
}
私の主な (しゃれは意図されていません) 問題は、任意の数のシーケンスで動作するように上記を一般化することです。どんな提案でも大歓迎です!ありがとう