2016-03-21 11 views
0

Şablon girişlerini genelleştirmek için daha büyük bir proje üzerinde çalışıyorum ve Boost MPL'yi C++ 03 kullanarak bazı endeksleri temiz bir şekilde doğrusallaştırmak için mücadele ediyorum. Sorunu bir örnekle göstermek en kolay yoldur (zavallı sözde kodumu affet).Boost MPL'yi Linearize Endekslerine Kullanma

N uzun uzunluklu vektörlerim var. N3 olduğu Say ve onlar gibi görünmek ki: Ben genel için bu dönüştürmek istediğiniz

vectorOfIndices = {0,4,1}; 

: gibi, bunların her biri için

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

, ben bir indeks ayrı vektör sakladığınız yaparak endeksi:

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

ben yardım tanımlayan en arıyorum meta işlevi/sınıf iki şablon parametreleri almalı bu bir genelleme olduğu tip mpl her iki :: vektör (içeren mpl :: int_ girişleri). İlk vektör bir dizi indisleri (yukarıdaki vektörOfIndices, fakat N uzunluğunda) içerecektir ve ikinci vektör bir uzunluk listesi (yukarıdaki v0, v1, v2 ... vN uzunlukları) içerecektir. Sonuç türü, genel dizini içeren bir mpl :: int_ olmalıdır.

cevap

0

Beni bir süreliğine okudum (çok fazla okuma ... çok ... meta programlamada bir öğrenme eğrisi çıkıyor), ama sonunda bir çalışma çözümüm var. Bu en güzel değil, ama benim: p. Herhangi birinin bunu iyileştirmek için önerileri varsa veya herhangi bir sorunla karşılaşırsa, sizden haber almak isterim.

/* 
* 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; 
    }; 
};