Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
template_metaprogramming_ru.docx
Скачиваний:
12
Добавлен:
01.07.2025
Размер:
774 Кб
Скачать
☆

Лямбда (Лямбда метафункции/выражения)

Лямбды выражение – все вызываемы метаданные. Состоят из двух основных механизмов: классы метафункций и выражения с использованием заполнителей.

Можно сгенерировать класс метафункции из класса boost::add_pointer <_1>, используя лямбды MPL:

template <class X>

struct two_pointers

: twice<typename mpl::lambda<boost::add_pointer<_1>>::type, X>

{};

BOOST_STATIC_ASSERT

((

boost::is_same

<

typename two_pointers<int>::type,

int**

>::value

));

Т.о. заполняемое выражение сохраняет результат между вызовами различных инстацнирований во внешней лямбда метафункции.

Хотя основная цель использования лямбды состоит в том, чтобы превратить placeholder выражения в классы метафункций, mpl::lambda может принять любое выражение лямбды, даже если это уже - класс метафункции. В этом случае лямбда возвращает свой неизменный аргумент. Алгоритмы MPL, такие как transform вызывают лямбду, прежде, чем обратиться к результату класса метафункции, это позволяет таким алгоритмам работать одинаково хорошо с любым видом лямбда выражений.

Применим эту стратегию к twice, чтобы не передавать в нее лямбду явно:

template <class F, class X>

struct twice :

apply_helper

<

typename mpl::lambda<F>::type,

typename apply_helper

<

typename mpl::lambda<F>::type,

X

>::type

>

{};

Теперь можно использовать twice с классами метафункций и заполнителями:

int* x;

twice<add_pointer_f, int>::type p = &x; // передаем класс метафункции

twice<boost::add_pointer<_1>, int>::type q = &x; // передаем метафункцию с заполнителем

Частичное приложение метафункции

Лямбды обеспечивают намного больше чем только способность передать метафункцию как аргумент, есть также дополнительные возможности, которые делают лямбды неотъемлемой частью почти каждой метапрограммной задачи.

Рассмотрите выражение лямбды mpl::plus<_1, _1>. Одинаковый аргумент передан обоим параметрам plus, таким образом число добавляется к самому себе. Двойная метафункция plus используется, чтобы создать унарное лямбда выражение. Другими словами мы создали совершенно новое вычисление! Передавая не-заполнитель (non-placeholder) в качестве одного из аргументов, можно построить унарное лямбда выражение, которое добавляет постоянное значение, например 42 к своему аргументу:

mpl::plus<_1, mpl::int_<42>>

Композиция метафункций:

Лямбда выражения могут использоваться для сборки сложных метафункций из ряда простых. Например, следующее выражение, которое умножает результат суммы и разницы двух чисел,различием, является составой метафункцией из трех простых метафункций: умножения, сложения и вычитания:

mpl::multiplies<mpl::plus<_1,_2>, mpl::minus<_1,_2>>

Вычисляя лямбда выражение, MPL проверяет аргументы на предмет того, не являются ли они сами вложенными лямбда выражениями и если да, то они вычисляются в первую очередь, корректно передавая результат во внешнее выражение. Такая очередность работы с лямбда выражениями привносит большую гибкость и строгую логику.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]