2016-03-21 11 views
0

私は、より大きなプロジェクトでテンプレートのインスタンスを一般化するために取り組んでおり、C++ 03でBoost MPLを使っていくつかのインデックスをきれいに線形化するのに苦労しています。私の問題を例で表示するのが最も簡単です(貧弱な擬似コードを許してください)。Boost MPLを使用してインデックスを線形化する

私は任意の長さのN個のベクトルを持っています。 Nが3であると言う、彼らはのように見えると言う:私は全体的に、これらを変換したい

vectorOfIndices = {0,4,1}; 

:のように、それらのそれぞれについて

v0 = {1,2,3}; 
v1 = {4,5,6,7,8}; 
v2 = {9,10}; 

、私はインデックスは別のベクトルに格納されています

0*sizeof(v1)*sizeof(v2) + 4*sizeof(v2) + 1; 

を私が定義する助けを探していたメタ関数/クラスは、両方のタイプのMPLの2つのテンプレートパラメータに取るべき本を一般化したものです::ベクトル(MPLを含む:: INT_エントリを:実行して、インデックス)。最初のベクトルはインデックスのシーケンス(上記のvectorOfIndicesで長さはN)を含み、2番目のベクトルは長さのリスト(上記のv0、v1、v2 ... vNの長さ)のリストを含みます。結果の型は、全体のインデックスを含むmpl :: int_でなければなりません。

答えて

0

私はしばらくして(たくさんの読書...たくさんのメタプログラミングには急な学習曲線がありますが)、私は最終的に実用的な解決策を得ました。それは一番美しいものではありませんが、それは私のものです。誰かがそれを改善するための提案を持っている、または問題を見て、私はあなたから聞くことを愛するだろう。

/* 
* Computes and absolute index from a sequence of indices and vectors lengths. 
* Example: 
* 
* Vectors: 
* v0 = {1, 2, 3} 
* v1 = {2} 
* v2 = {4, 5, 6, 7} 
* 
* Inputs: 
* lengthsOfVectors = {3, 1, 4} 
* indexSequence = {2, 0, 3} 
* 
* Result: 
* type = 2*(1*4) + 0*(4) + 3 
* 
*/ 
struct ComputeAbsoluteIndex 
{ 
    template <typename lengthsOfVectors, typename indexSequence> struct apply 
    { 
     // Number of indices in sequence. 
     typedef typename mpl::size<indexSequence>::type numberOfIndicesInSequence; 

     // Forward sequence to iterate over number of indices in sequence. 
     typedef typename mpl::range_c<int, 0, numberOfIndicesInSequence::value>::type indexSequenceRange; 

     // Forward iterator that points to start of lengths of vectors. 
     // Add one since offset contributions are computed by multiplying the current index, from the index sequence, by the lengths subsequent vectors. 
     typedef typename mpl::next<typename mpl::begin<lengthsOfVectors>::type >::type lengthsOfVectorsStart; 

     // Forward iterator that points to the end of lengths of vectors. 
     typedef typename mpl::end<lengthsOfVectors>::type lengthsOfVectorsEnd; 

     typedef typename mpl::lambda // Helper metafunction class to multiply lengths. 
     < 
      mpl::fold // Loop over lengths to multiply. 
      < 
       mpl::_1, // Sequence of lengths to multiply. 
       mpl::int_<1>, // Initial multiplier of one. 
       typename mpl::lambda // Wrap multiply in lambda such that place holders (_1 and _2) are replaced properly. 
       < 
        mpl::multiplies<mpl::_1, mpl::_2 > 
       >::type 
      > 
     >::type multiplySequence; 

     typedef typename mpl::fold // Loop over each index in index sequence. 
     < 
      indexSequenceRange, // Forward Sequence to iterate over number of indices in index sequence. 
      mpl::int_<0>, // Initial total index of zero. 
      mpl::plus // Add offsets. 
      < 
       mpl::_1, // Initial state to start (zero), then result of previous addition for each following iteration. 
       mpl::multiplies // Multiply current index from index sequence by remaining lengths. 
       < 
        mpl::at<indexSequence, mpl::_2 >, // Get current index from index sequence. 
        multiplySequence::apply // Invoke helper metafunction class to multiply lengths. 
        < 
         mpl::iterator_range // Create Forward Sequence that iterates over lengths to multiply. 
         < 
          mpl::advance<lengthsOfVectorsStart, mpl::_2>, // Advance iterator start to multiply proper lengths. 
          lengthsOfVectorsEnd 
         > 
        > 
       > 
      > 
     >::type type; 
    }; 
}; 
関連する問題