Boost.MPLのプレースホルダー

Boost.MPLにもmpl::_、mpl::_1、mpl::_2...といったプレースホルダーがあり、
メタ関数の引数を部分評価できます。

#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/placeholders.hpp>

template <class T>
struct add_pointer {
    typedef T* type;
};

namespace mpl = boost::mpl;

int main()
{
    typedef mpl::apply<add_pointer<mpl::_>,  int>::type type;
//  typedef mpl::apply<add_pointer<mpl::_1>, int>::type type; // どちらでも同じ

    BOOST_STATIC_ASSERT((boost::is_same<type, int*>::value));
}


以下は引数を複数渡すケースで、第一引数にmpl::_1、第二引数にmpl::_2を使用していますが

#include <utility>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/placeholders.hpp>

template <class Arg1, class Arg2>
struct make_pair_type {
    typedef std::pair<Arg1, Arg2> type;
};

namespace mpl = boost::mpl;

int main()
{
    typedef
        mpl::apply<make_pair_type<mpl::_1, mpl::_2>, int, char>::type
    type;

    BOOST_STATIC_ASSERT((boost::is_same<type, std::pair<int, char> >::value));
}

mpl::_は順番の情報を持っているらしく、make_pair_type<mpl::_, mpl::_>としても
同じ結果になるんだそうです。

#include <utility>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/placeholders.hpp>

template <class Arg1, class Arg2>
struct make_pair_type {
    typedef std::pair<Arg1, Arg2> type;
};

namespace mpl = boost::mpl;

int main()
{
    typedef
        mpl::apply<make_pair_type<mpl::_, mpl::_>, int, char>::type
    type;

    BOOST_STATIC_ASSERT((boost::is_same<type, std::pair<int, char> >::value));
}

どうやってるんでしょうね。