- •Вычисления значений
- •Пример:
- •Вычисления типов
- •Преимущества мета подхода:
- •Польза использования mpl:
- •Числовая метафункция
- •Свойства
- •Метаданные
- •Специализация
- •Первичный шаблон:
- •Инстанцирование:
- •Метафункции
- •Полиморфизм
- •Возможности свойств:
- •Организация свойств в Boost:
- •Пример:
- •Типовые ассоциации
- •Альтернатива:
- •Метафункции Продвижение (пересылка) метафункций
- •Класс метафункции
- •Формат:
- •Числовые
- •Пример:
- •Нульарные
- •Метрический анализ (Анализ размерностей)
- •Метрики
- •Величины
- •Сложение и вычитание
- •Умножение
- •Класс метафункции
- •Деление
- •Пример:
- •Метафункции высшего порядка (Каскады вложенных вызовов)
- •Использование apply:
- •Заполнители
- •Безымянный заполнитель:
- •Определение выражений с заполнителями
- •Лямбда (Лямбда метафункции/выражения)
- •Частичное приложение метафункции
- •Лямбда и Шаблоны Неметафункции
- •Обертки
- •Выбор типа
- •Ленивый Выбор Типа
- •Логические Операторы
- •Целочисленные обертки
- •Составные Операторы
- •Операторы с булевым значением:
- •Операторы для сравнения значений:
- •Операторы для интегральных значений:
- •Побитовые операторы:
- •Арифметические операторы:
- •Целочисленная «стенография»
- •Интегральные последовательности
- •Формат:
- •Последовательности
- •Концепции
- •Итераторы
- •Двунаправленные
- •Произвольные
- •Последовательности
- •Двунаправленные
- •Произвольные
- •Расширенные
- •Ассоциативные
- •Требования
- •Расширения
- •Расширенные ассоциативные последовательности
- •Алгоритмы и последовательности
- •Итераторы
- •Равенство
- •Операции Внутренние операции с последовательностей
- •Наследование
- •Создание последовательности
- •Реализация:
- •Создание итератора
- •Преимущества полной специализации перед частичной:
- •Добавление расширения
- •Алгоритмы
- •Абстракция:
- •Stl алгоритмы
- •Детали правильного использования stl:
- •Mpl алгоритмы
- •Различия stl и mpl алгоритмов:
- •Пример:
- •Вставки
- •Пример 1:
- •Пример 2:
- •Пример 3:
- •Фундамент алгоритмов
- •Пример:
- •Запрашиваемые алгоритмы
- •Последовательности (Алгоритмы, создающие последовательности)
- •Синонимы функциональных алгоритмов:
- •Создание алгоритма
- •Итераторы «Просмотр» и итераторы-адаптеры
- •Концепция просмотра
- •Применение просмотра Сравнения значений элементов последовательности:
- •Объединение множественных (мульти-) последовательностей
- •Упрощение 1
- •Упрощение 2 (создание просмотра)
- •Уход от ненужного вычисления
- •Выборочная обработка элемента
- •Итератор-адаптер
- •Создание просмотра
- •Реализация итератора-адаптера для zip_view.
- •Диагностика
- •Отладка ошибок
- •Трассировка инстанцирования
- •Исправленный пример:
- •Форматы сообщений об ошибках
- •Блок «with»
- •Устранение параметров шаблона по умолчанию
- •Глубокий typedef
- •Инструменты
- •Несколько компиляторов
- •(Статические Утверждения)
- •Формат:
- •Формат:
- •Индивидуальные сообщения утверждений
- •Настройка предиката:
- •(Генерирование встроенных сообщений)
- •Формат:
- •Выбор стратегии:
- •Тип печати
- •Кросс этапность компиляции/выполнения
- •Печать типов:
- •Тип посещения:
- •Выбор реализаций
- •Специализация шаблонов классов
- •Тег диспетчеризации
- •Выбор структуры
- •Композиция классов
- •Указатели на функцию
- •Ослабление типизации
- •Пример:
- •Обобщение:
- •Динамический полиморфизм
- •Автоматизация
- •Сохранение интерфейса
- •Рекуррентный шаблон
- •Формат:
- •Генерирование функций
- •Управление разрешением перегрузки
- •Явное управление множеством перегрузки
- •Документация mpl Последовательности
- •Концепции
- •(Прямая последовательность)
- •(Двунаправленная Последовательность)
- •(Последовательность произвольного доступа)
- •(Расширенная последовательность)
- •(Расширенная последовательность начала)
- •(Расширенная последовательность конца)
- •(Ассоциативная последовательность)
- •(Расширенная ассоциативная последовательность)
- •(Обертка интегральной последовательности )
- •(Переменная последовательность)
- •Представления
- •Метафункции (Внутренние)
- •Итераторы
- •Концепции
- •(Прямой итератор)
- •(Двунаправленный итератор)
- •(Итератор произвольного доступа)
- •Метафункции
- •Алгоритмы
- •Концепции
- •(Инсертер: механизм вставок)
- •Инсертеры (инсертер: механизм вставок)
- •Итеративные алгоритмы
- •Запрашиваемые алгоритмы
- •Преобразования
- •Метафункции
- •Концепции Метафункция
- •Метафункциональный класс
- •Лямбда выражения
- •Заполнители
- •Тэг диспетчеризированные метафункции
- •Числовые метафункции
- •Тривиальные метафункции
Пример:
template <class Seq>
struct my_reverse
: mpl::fold<
Seq,
typename mpl::clear<Seq>::type,
mpl::push_front<_,_>
>
{};
//+--------------------------------------------------------------------+
int main()
{
typedef mpl::vector<Char,Int,Float> t_list;
t_list::item0 obj;
obj.ch = 'a';
obj.func();
typedef my_reverse<t_list>::type rev_list;
rev_list::item0 r_obj;
r_obj.func();
return 0;
}
reverse_fold
Особенность работы mpl::fold: когда он используется с push_front, результат всегда выходит в обратном порядке. Поскольку списки (mpl::list) могут быть построены только с push_front, то крайне возникает потребность применять к результирующей последовательности дополнительно mpl::reverse, что крайне неэффективно, потому MPL также предоставляет метафункцию reverse_fold, которая обрабатывает элементы в обратном порядке.
Для последовательностей, который могут быть пройдены только в прямом направлении используется следующий подход: вместо действий с «головой» последовательности и сворачиванием «хвоста» через mpl::fold, выполняется mpl::fold с «хвостом», а затем действия с «головой»:
reverse_fold(Seq, Prev, BinaryOp) :=
if Seq is empty then:
Prev
else: // process the rest of the sequence
BinaryOp( // and combine with the first element
reverse_fold(tail(seq), Prev, BinaryOp),
head(seq)
)
Вместо обработки каждого элемента последовательности в процессе «раскрутки» рекурсии, обработка происходит наоборот, в процессе «сворачивания» рекурсии.
Можно вести обработку в обоих направлениях, что поддерживается метафункцией mpl::reverse_fold, которая принимает в качестве четвертого аргумента возможность выбора этапа, на котором должна вестись обработка: раскрутка/сворачивание рекурсии.
reverse_fold(Seq, Prev, OutOp, InOp = _1) :=
if Seq is empty then:
Prev
else:
OutOp( // Сворачивание рекурсии
reverse_fold( // Раскрутика рекурсии
tail(Seq),
InOp(Prev,head(Seq)), // just Prev by default
OutOp,
InOp),
head(Seq)
)
Такое обобщение позволяет максимально эффективно использовать рекурсивное поведение. По умолчанию используется операция InOp, которая просто возвращает свой первый аргумент, что эквивалентно когда InOp не используется, то Prev просто передается рекурсивному вызову.
iter_fold
Вместо того, чтобы делать обход по элементам последовательности, мы можем перебирать значения итератора. Это полезно, например, если мы хотим вести обработку последовательного поддиапазона входной последовательности. Для этого используется iter_fold:
iter_fold(Seq, Prev, BinaryOp) :=
if Seq is empty then:
Prev
else: // combine the first position with Prev
iter_fold( // and process the rest recursively
tail(Seq)
, BinaryOp(Prev, begin(Seq))
, BinaryOp
)
Основное различие между fold и iter_fold в том, что вторым аргументом BinaryOp является итератор, а не элемент последовательности.
reverse_iter_fold
Также поддерживается полное обобщение reverse_iter_fold:
reverse_iter_fold(Seq, Prev, OutOp, InOp = _1) :=
if Seq is empty then:
Prev
else:
OutOp(
reverse_iter_fold(
tail(Seq),
InOp(Prev, begin(Seq)),
OutOp,
InOp),
begin(Seq)
)
