boost::mpl を使用した twice の実装


[お題]
The lambda Metafunction に書かれている、twice を mpl::lambda や mpl::apply を使用して定義してみる。

// 元のメタ関数
template <class F, class X>
struct twice
   : apply1<
         typename mpl::lambda<F>::type
       , typename apply1<
             typename mpl::lambda<F>::type
           , X
         >::type
     >
{};


// boost::add_pointer が 2回展開される
BOOST_MPL_ASSERT(( boost::is_same<
    twice<boost::add_pointer<_>, int>::type,
    int**
> ));


[実装]

#include <boost/type_traits/add_pointer.hpp>
#include <boost/type_traits/is_same.hpp>

#include <boost/mpl/assert.hpp>
#include <boost/mpl/lambda.hpp>
#include <boost/mpl/apply.hpp>


namespace mpl = boost::mpl;

typedef mpl::lambda<mpl::apply1<mpl::_1, mpl::_2> >::type once;

BOOST_MPL_ASSERT(( boost::is_same<
    once::apply<boost::add_pointer<mpl::_1>, int>::type,
    int*
> ));

typedef mpl::lambda<
    once::apply<mpl::_1, once::apply<mpl::_1, mpl::_2> >
>::type twice;

BOOST_MPL_ASSERT(( boost::is_same<
    twice::apply<boost::add_pointer<mpl::_>, int>::type,
    int**
> ));

int main(){}


また once の部分ですが mpl::apply1 ではなく、mpl::apply を使用するとうまく展開が出来ないみたいです。

typedef mpl::lambda<mpl::apply<mpl::_1, mpl::_2> >::type once;
once::apply<boost::add_pointer<mpl::_1>, int>::type; // mpl::_2 が返ってきている?

原因を調べようと思ったけど力尽きました……。


[boost]
ver 1.45.0