boost::mpl::placeholderの概観

#include <boost/mpl/int.hpp>
#include <boost/mpl/plus.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/assert.hpp>

using namespace boost::mpl;

// STEP0
BOOST_MPL_ASSERT_RELATION( (    
  apply<
    plus<_1,_2>,
    int_<6>, int_<7>
  >::type::value), ==, 13 );

// STEP0': synonym
// 実際はint_<0>ではなくintegral_c<int,0>
BOOST_MPL_ASSERT_RELATION( (    
  apply2<
    plus< _1, _2, int_<0>, int_<0>, int_<0> >,  // plus is 5-ary Metafunction, by default
    int_<6>, int_<7>
  >::type::value), ==, 13 );
// STEP1
// PlaceholderExpressionだけではコードが意味を持たないのでlambdaで分解する
// lambdaはLambdaExpressionをMetafunctionClassに変換する
BOOST_MPL_ASSERT_RELATION( (  
  apply_wrap2<
    lambda< plus< _1, _2, int_<0>, int_<0>, int_<0> > >::type,  // lambda filter
    int_<6>, int_<7>
  >::type::value), ==, 13 );
// STEP2
BOOST_MPL_ASSERT_RELATION( (    
  apply_wrap2<
    protect<
      bind5<
        quote5<plus>,   // 5-ary Metafunction to 5-ary MetafunctionClass
        arg<1>, arg<2>,   // <-- lambda<_1>::type, lambda<_2>::type,
        int_<0>, int_<0>, int_<0>
      >
    >,
    int_<6>, int_<7>
  >::type::value), ==, 13 );
// KERNEL
// 2-ary(binary) MetafunctionClassとして機能する
struct bind5_of_STEP2 {
  // Still 5 arguments!, all that bind5_of_STEP2 can't leave behind,
  // waiting for U1 and U2...
  template <typename U1 = void_, typename U2 = void_,
    typename U3 = void_, typename U4 = void_, typename U5 = void_>
  struct apply : apply_wrap5<
    quote5<plus>,
    typename apply_wrap5< arg<1>, U1, U2, U3, U4, U5 >::type, // = U1
    typename apply_wrap5< arg<2>, U1, U2, U3, U4, U5 >::type, // = U2
    int_<0>, int_<0>, int_<0>
  > {
  };
};

// STEP3
BOOST_MPL_ASSERT_RELATION( (
  apply_wrap2<
  protect<bind5_of_STEP2>,   // protect, who are you? cf. is_bind_template
    int_<6>, int_<7>
  >::type::value), ==, 13 );
// STEP4
BOOST_MPL_ASSERT_RELATION( (
  apply_wrap2<
    bind5_of_STEP2, 
    int_<6>, int_<7>
  >::type::value), ==, 13 );
int _tmain(int argc, _TCHAR* argv[]) {
  return 0;
}