2011-10-28 3 views
1

次の構文を使用して、タイプのmplベクトルを作成します。タイプとmpl :: vectorを新しいベクトルに結合する方法

struct Struct1{ 
    typedef int type; 
}; 
struct Struct2{ 
    typedef float type; 
}; 
template<typename T> struct TypeReader{ 
    typedef typename T::type type; 
}; 

int main() 
{ 
    typedef bm::vector<Struct1,Struct2> MPLVector; 
    typedef bm::transform<MPLVector, TypeReader<bm::_1>>::type TypeList; 
    static_assert(bm::equal<TypeList, bm::vector<int,float> >::value, "Is not same"); 
} 

これまでのところ、これは期待どおりに機能します。今私がしたいのは以下の通りです

struct Struct3{ 
    typedef bm::vector<char,double> type; 
}; 
typedef bm::vector<Struct1,Struct2,Struct3> MPLVector; 
typedef bm::transform<MPLVector, TypeReader<bm::_1>>::type TypeList; 
static_assert(bm::equal<TypeList, bm::vector<int,float,char,double> >::value, "Is not same"); 

これは機能しません。では、MetaFunction構造体を、typedefとmpl :: vectorの両方で動作するように変更する必要はありますか?
これが不可能な場合は、すべての型typedefをmplベクトルに変更するとこれを行うことは可能でしょうか?

答えて

2

mpl::transformとは考えられません。ソースシーケンス内の1つの要素から結果のシーケンスにいくつかの要素を生成する必要があるためです。しかし、これはmpl::is_sequenceと専門とともに、mpl::foldを行うことができます。

// Default case 
template < typename Seq, typename TWrapper, typename Enable = void > 
struct Flatten_imp 
    : mpl::push_back< Seq, typename TWrapper::type > 
{ 
}; 

// Sequence case 
template < typename Seq, typename TWrapper > 
struct Flatten_imp< 
    Seq, 
    TWrapper, typename 
    boost::enable_if< 
     mpl::is_sequence< typename 
      TWrapper::type 
     > 
    >::type 
> 
{ 
    typedef mpl::joint_view< 
     Seq, typename 
     TWrapper::type 
    > type; 
}; 

template < typename Seq > 
struct Flatten 
    : mpl::fold< Seq, mpl::vector<>, Flatten_imp< mpl::_, mpl::_ > > 
{} 

int main() 
{ 
    typedef mpl::vector< Struct1, Struct2, Struct3 > MPLVector; 
    typedef Flatten<MPLVector>::type TypeList; 

    static_assert(
     mpl::equal< 
      TypeList, 
      mpl::vector< int, float, char, double > 
     >::value, "Is not same"); 
} 

あなたが平坦化は再帰的になりたい場合は、あなたがそれを追加する前にシーケンスを平らにするFlatten_implFlattenを呼び出すことができます。ただし、シーケンスにラッパーが含まれ、直接型ではない場合にのみ、この再帰が機能することに注意してください。

struct Struct3 
{ 
    typedef mpl::vector< mpl::identity<char>, mpl::identity<double> > type; 
} 
+0

完全な答えをありがとう。フォールドは私の心には決して来なかったが、あなたの解決策は本当にいいです。 – mkaes

+0

良い答え。私は 'is_sequence'について知らなかった。 – pmr

0

パラメータがシーケンス(mplベクトル、融合リスト/ベクトル/タプル)の場合は、TypeReaderを特化する必要があります。その場合

は、(ターゲット・タイプにパラメータのシーケンスからコピーする)mpl::copy

mpl::back_inserterのパワーを兼ね備え私は現在、これをデモするための時間を持っていません。シーケンスのコンセプトを専門にするヒントについては、boost::enable_ifをご覧ください。しかし、ProofOfConceptは専門にするだけで簡単に行うことができますtemplate <typename> mpl::vector

+0

「TypeReader」は実際よりも簡単に発音します。 – pmr

+0

@ pmr:私はすでにヒントを編集していました。私は知っていますが、私は今PoCを行うことができません – sehe

関連する問題