尊敬的Matthieu,您的解决方案运行良好。
对于我的框架,我需要一种更通用的方法来实现类型组合,所以我开发了一些似乎有效的不同方法。
template < class Seq >
class combine_view {
typedef typename mpl::transform<Seq, mpl::begin<_1> >::type Pos_begin;
typedef typename mpl::transform<Seq, mpl::end<_1> >::type Pos_end;
public:
typedef combine_iterator<Seq, Pos_begin> begin;
typedef combine_iterator<Seq, Pos_end> end;
typedef combine_view type;
};
提供序列开始和结束的combine_iterator必须知道序列和提供位置的迭代器,例如以下实现:
template < typename Seq, typename Itrs >
struct combine_iterator {
typedef mpl::forward_iterator_tag category;
typedef Seq seq;
typedef typename transform <
Itrs,
deref<_1>
>::type
type;
};
现在你必须告诉boost-mpl如何到达下一个位置,专门进行mpl::next操作。
namespace boost {
namespace mpl {
template <class Seq, class Pos>
struct next< combine_iterator<Seq, Pos> > {
typedef typename SequenceCombiner<Seq,Pos>::next next_Pos;
typedef combine_iterator< Seq, next_Pos > type;
};
} // mpl
} // boost
最后,组合器技巧可以使用mpl::fold来实现,就像在这个类中一样:
template <class Seq, class ItrSeq>
class SequenceCombiner {
template < class _Seq = mpl::vector<int_<1> > >
struct StateSeq {
typedef typename pop_front<_Seq>::type sequence;
typedef typename mpl::at< _Seq, int_<0> >::type state;
typedef _Seq type;
};
template < class _Seq, class _State >
struct set_state {
typedef StateSeq< typename push_front<_Seq, _State >::type > type;
};
struct NextOp {
template < typename Out, typename In, typename Enable = typename Out::state >
class apply {
typedef typename Out::sequence seq;
typedef typename Out::state new_state;
typedef typename mpl::at<In,int_<0> >::type in_seq;
typedef typename mpl::at<In,int_<1> >::type in_itr;
typedef typename mpl::push_back<seq, in_itr >::type new_seq;
public:
typedef typename set_state<new_seq, int_<0> >::type type;
};
template < typename Out, typename In >
class apply<Out,In,mpl::int_<1> > {
typedef typename Out::sequence seq;
typedef typename Out::state state;
typedef typename mpl::at<In,int_<0> >::type in_seq;
typedef typename mpl::at<In,int_<1> >::type in_itr;
typedef typename mpl::begin<in_seq>::type Itr_begin;
typedef typename mpl::next<in_itr>::type Itr_next;
typedef typename mpl::end<in_seq>::type Itr_end;
typedef typename mpl::if_< boost::is_same<Itr_next,Itr_end>,
typename mpl::push_back<seq,Itr_begin>::type,
typename mpl::push_back<seq,Itr_next>::type
>::type
new_seq;
typedef typename mpl::if_< boost::is_same<Itr_next,Itr_end>,
mpl::int_<1>,
mpl::int_<0>
>::type
new_state;
public:
typedef typename set_state<new_seq, new_state>::type type;
};
};
typedef typename mpl::fold<
typename mpl::zip_view< mpl::vector<Seq, ItrSeq > >::type,
StateSeq<>,
NextOp
>::type
StateResult;
public:
typedef typename mpl::if_< boost::is_same< typename StateResult::state, int_<1> >,
typename mpl::transform< Seq, mpl::end<_1> >::type,
typename StateResult::sequence >::type
next;
};
让我向您展示如何在测试应用程序中使用生成的新序列视图。
struct A {};
struct B {};
struct C {};
struct D {};
struct E {};
struct F {};
struct G {};
struct H {};
struct I {};
namespace {
struct PrintTypeId {
template <class T>
void operator()(T) const
{ std::cout << typeid(T).name() << " "; }
};
struct PrintSeq {
template < typename T >
void operator()(T) {
mpl::for_each<T>( PrintTypeId() );
std::cout << "\n";
}
};
}
int main() {
BEGIN_TESTING( Mpl Sequence Combiner Test);
typedef mpl::vector<A,B,C> seq1;
typedef mpl::vector<D,E,F> seq2;
typedef mpl::vector<G,H,I> seq3;
typedef mpl::combine_view< mpl::vector<seq1,seq2,seq3> > cv;
mpl::for_each< cv >( PrintSeq() );
END_TESTING;
}
..:: Testing Mpl Sequence Combiner Test ::..
1A 1D 1G
1B 1D 1G
1C 1D 1G
1A 1E 1G
1B 1E 1G
1C 1E 1G
1A 1F 1G
1B 1F 1G
1C 1F 1G
1A 1D 1H
1B 1D 1H
1C 1D 1H
1A 1E 1H
1B 1E 1H
1C 1E 1H
1A 1F 1H
1B 1F 1H
1C 1F 1H
1A 1D 1I
1B 1D 1I
1C 1D 1I
1A 1E 1I
1B 1E 1I
1C 1E 1I
1A 1F 1I
1B 1F 1I
1C 1F 1I
安德烈·里戈尼·加洛拉