我正在开发一个更大的项目来概括模板瞬时,并且正在努力使用Boost MPL和C ++ 03来干净地线性化一些索引。用一个例子来展示我的问题是最容易的(原谅我的可怜的伪代码)。
我有N个任意长度的向量。说N是3,并说它们看起来像:
v0 = {1,2,3};
v1 = {4,5,6,7,8};
v2 = {9,10};
对于每一个,我有一个索引存储在一个单独的向量中,如:
vectorOfIndices = {0,4,1};
我想通过执行以下操作将这些转换为整体索引:
0*sizeof(v1)*sizeof(v2) + 4*sizeof(v2) + 1;
我正在寻找帮助定义的元函数/类是对它的概括,它应该包含两个模板参数,类型mpl :: vector(包含mpl :: int_ entries)。第一个向量将包含索引序列(vectorOfIndices,但长度为N),第二个向量将包含长度列表(上面的v0,v1,v2 ... vN的长度)。结果类型应该是包含整体索引的mpl :: int_。
答案 0 :(得分:0)
花了一段时间(很多阅读...很多......元编程有一个陡峭的学习曲线),但我终于有了一个有效的解决方案。它不是最漂亮的,但它是我的:p。如果有人有改进建议或看到任何问题,我很乐意听取您的意见。
/*
* 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;
};
};