Boost MPL Placeholders и Lambda

В настоящее время я делаю некоторые доказательства на образцах образцов с boost:: mpl, и у меня возникают некоторые трудности с пониманием того, как функция лямбда позволяет использовать заполнители.

Я понимаю, что я могу обернуть метафайлы в классах metafunction, чтобы позволить функциям более высокого порядка иметь доступ к вложенной функции приложения и поняли, что вы можете избежать этих усилий, используя mpl:: lambda wrapping metafunction, который позволяет владельцам мест.

Как это работает? У меня возникают проблемы, обертывая голову вокруг того, что на самом деле делают ламы и заполнители под крышками.

Ответ 1

См. руководство Boost.MPL: заполнитель является классом метафонов формы mpl::arg<X>. Класс metafunction - это класс, содержащий метафункцию apply.

template <int N> struct arg; // forward declarations
struct void_;

template <>
struct arg<1>
{
    template <
      class A1, class A2 = void_, ... class Am = void_>
    struct apply
    {
        typedef A1 type; // return the first argument
    };
};
typedef arg<1> _1

Задача mpl::lambda заключается в том, чтобы включить выражения-заполнители в классы metafunction. Это делается путем вложения класса metafunction, такого как this:

template<
      typename X
    , typename Tag = unspecified
    >
struct lambda
{
    typedef unspecified type;
};

Если x является выражением-заполнителем в общей форме X<a1,...an>, где X является шаблоном класса и a1,... an являются произвольными типами, встроенный неопределенный тип f эквивалентен

typedef protect< bind<
      quoten<X>
    , lambda<a1>::type,... lambda<an>::type
> > f;

в противном случае f идентично X. Метафунг apply оценивает выражение лямбда, обращаясь к встроенному типу.

В MPL manual вы можете найти определения protect, bind и quote. Они все обертывают вокруг своих аргументов, чтобы отложить оценку как можно дольше.