I have the following primary template:
template<size_t pos, size_t lev>
struct Sol;
and I specialize it for some pos values like so:
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;
}
but I get that Sol
expected size_t
and got mpl_::_1
. I know in this case I could probably omit this fold thing im trying to do and just declare value to be the sum of the one level lower values of the other two Sol
structs for pos
of 4 and 6..but I was wondering if this could be repaired in case the vector_c
was a bit long to type out?
Thanks..
The code below will do what you want. I've made a few changes.
First, I wrapped the pos
non-type template parameter with a mpl::integral_c
. In general, when using Boost.MPL, it is advised to wrap all your non-type template parameters. This way, you never have to distinguish them later on.
Second, I used template metafunction forwarding. What this means is that instead of defining a template data member value
inside Sol
, I simply derive Sol
from a Boost.MPL template that contains that value. This will save you typing ::type::value
all over the place. Use good indentation to make the code easier to read.
Third, I wrapped your call to mpl::plus
inside mpl::fold
with a boost::mpl::lambda
. This is not stricly necessary for the code you gave, but it will be if you use Sol
itself inside another mpl::fold
expression with other placeholder arguments (the lambda wrapping will delay evaluation until the entire template has been parsed).
Fourth, I made a full specialization to stop the recursion on your lev
parameter. BTW, if you ever start doing compile-time computation ons lev
, the same advise applies: wrap it first into a 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
{};