使用mpl :: fold与占位符和我自己的struct mishap

时间:2012-08-06 23:33:07

标签: c++ templates template-meta-programming boost-mpl

我有以下主要模板:

template<size_t pos, size_t lev>
struct Sol;

我专注于一些像这样的pos值:

template<size_t lev>
struct Sol<0, lev>
{
    static const mpl::vector_c<size_t, 4, 6> jumps;
    static const size_t value =
        mpl::fold<jumps, mpl::integral_c<size_t, 0>, 
                  mpl::plus<Sol<_1, lev-1>::value, 
                            Sol<_2, lev-1>::value> >::type::value;
}

但我得到Sol预期size_t并得到mpl_::_1。我知道在这种情况下我可以省略这个折叠的东西,我试图做,只是声明值是Sol 4 {和pos的其他两个vector_c结构的一个较低值的总和..但我想知道如果{{1}}输出有点长,是否可以修复它?

谢谢..

1 个答案:

答案 0 :(得分:1)

以下代码可以满足您的需求。我做了一些改变。

首先,我将pos 非类型模板参数mpl::integral_c包装在一起。通常,在使用Boost.MPL时,建议包装所有非类型模板参数。这样,您以后就不必区分它们。

其次,我使用模板元函数转发。这意味着我不是在value中定义模板数据成员Sol,而是从包含该值的Boost.MPL模板中派生Sol。这样可以节省您在整个地方输入::type::value的费用。使用良好的缩进使代码更易于阅读。

第三,我使用mpl::plus将您的电话打包到mpl::fold boost::mpl::lambda内。这对于您提供的代码并不是非常必要,但如果您在另一个Sol表达式中使用mpl::fold本身与其他占位符参数(lambda包装将延迟评估,直到整个模板被解析) )。

第四,我完全专注于停止lev参数的递归。顺便说一句,如果您开始对lev进行编译时计算,则适用相同的建议:首先将其包装到mpl::integral_c

#include <boost/mpl/fold.hpp>
#include <boost/mpl/integral_c.hpp>
#include <boost/mpl/lambda.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/mpl/plus.hpp>
#include <boost/mpl/vector_c.hpp>

namespace mpl = boost::mpl;
using namespace mpl::placeholders;

// primary template
template<typename pos, size_t lev>
struct Sol;

// partial specialization for zero position
template<size_t lev>
struct Sol< mpl::integral_c<size_t, 0>, lev>
:
        mpl::fold<
                mpl::vector_c<size_t, 4, 6>, 
                mpl::integral_c<size_t, 0>,
                mpl::lambda<
                        mpl::plus<
                                Sol<_1, lev-1>, 
                                Sol<_2, lev-1>
                        > 
                > 
        >        
{};

// full specialization for zero position and level
template<>
struct Sol< boost::mpl::integral_c<size_t, 0>, 0>
:
        boost::mpl::integral_c<size_t, 0> // or whatever else you need
{};