boost::mpl を使った再帰処理


mpl::lambda で再帰処理を行うメタ関数を定義してみたいと思います。
今回は再帰処理で、0〜n までの合計を求めてみたいと思います。
通常の関数定義だとこんな感じです。

int
sum(int n){
    if(0 >= n){
        return n;
    }
    else{
        return n + sum(n-1);
    }
}


さて、通常は自分を呼び出して再帰を行いますが、mpl::lambda でメタ関数を定義する場合は、自分を呼び出すことが出来ません。
ですので、上記の処理をちょっと改造。

int sum(int);

struct sum_impl{
    template<typename F>
    int operator ()(int n, F f){
        if(0 >= n){
            return n;
        }
        else{
            return n + sum(n-1);
        }
    }
};

int sum(int n){
    return sum_impl()(n, sum_impl());
}

こんな感じで、引数に再帰を行う関数を渡すようにします。
あとはこれをメタ関数に変換するだけです。

#include <boost/static_assert.hpp>
#include <boost/mpl/lambda.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/greater_equal.hpp>
#include <boost/mpl/minus.hpp>
#include <boost/mpl/plus.hpp>

namespace mpl = boost::mpl;

typedef mpl::lambda<
    mpl::if_<
        mpl::greater_equal<mpl::int_<0>, mpl::_1>,
        mpl::_1,
        mpl::plus<
            mpl::_1,
            mpl::apply2<
                mpl::_2,
                mpl::minus<mpl::_1, mpl::int_<1> >,
                mpl::_2
            >
        >
    >
>::type sum_impl;

typedef mpl::lambda<sum_impl::apply<mpl::_1, sum_impl> >::type sum;

BOOST_STATIC_ASSERT(( sum::apply<mpl::int_<4> >::type::value == 10 ));

これで再帰処理を行うことが出来ました。


[boost]
ver 1.45.0