- •Вычисления значений
- •Пример:
- •Вычисления типов
- •Преимущества мета подхода:
- •Польза использования mpl:
- •Числовая метафункция
- •Свойства
- •Метаданные
- •Специализация
- •Первичный шаблон:
- •Инстанцирование:
- •Метафункции
- •Полиморфизм
- •Возможности свойств:
- •Организация свойств в Boost:
- •Пример:
- •Типовые ассоциации
- •Альтернатива:
- •Метафункции Продвижение (пересылка) метафункций
- •Класс метафункции
- •Формат:
- •Числовые
- •Пример:
- •Нульарные
- •Метрический анализ (Анализ размерностей)
- •Метрики
- •Величины
- •Сложение и вычитание
- •Умножение
- •Класс метафункции
- •Деление
- •Пример:
- •Метафункции высшего порядка (Каскады вложенных вызовов)
- •Использование apply:
- •Заполнители
- •Безымянный заполнитель:
- •Определение выражений с заполнителями
- •Лямбда (Лямбда метафункции/выражения)
- •Частичное приложение метафункции
- •Лямбда и Шаблоны Неметафункции
- •Обертки
- •Выбор типа
- •Ленивый Выбор Типа
- •Логические Операторы
- •Целочисленные обертки
- •Составные Операторы
- •Операторы с булевым значением:
- •Операторы для сравнения значений:
- •Операторы для интегральных значений:
- •Побитовые операторы:
- •Арифметические операторы:
- •Целочисленная «стенография»
- •Интегральные последовательности
- •Формат:
- •Последовательности
- •Концепции
- •Итераторы
- •Двунаправленные
- •Произвольные
- •Последовательности
- •Двунаправленные
- •Произвольные
- •Расширенные
- •Ассоциативные
- •Требования
- •Расширения
- •Расширенные ассоциативные последовательности
- •Алгоритмы и последовательности
- •Итераторы
- •Равенство
- •Операции Внутренние операции с последовательностей
- •Наследование
- •Создание последовательности
- •Реализация:
- •Создание итератора
- •Преимущества полной специализации перед частичной:
- •Добавление расширения
- •Алгоритмы
- •Абстракция:
- •Stl алгоритмы
- •Детали правильного использования stl:
- •Mpl алгоритмы
- •Различия stl и mpl алгоритмов:
- •Пример:
- •Вставки
- •Пример 1:
- •Пример 2:
- •Пример 3:
- •Фундамент алгоритмов
- •Пример:
- •Запрашиваемые алгоритмы
- •Последовательности (Алгоритмы, создающие последовательности)
- •Синонимы функциональных алгоритмов:
- •Создание алгоритма
- •Итераторы «Просмотр» и итераторы-адаптеры
- •Концепция просмотра
- •Применение просмотра Сравнения значений элементов последовательности:
- •Объединение множественных (мульти-) последовательностей
- •Упрощение 1
- •Упрощение 2 (создание просмотра)
- •Уход от ненужного вычисления
- •Выборочная обработка элемента
- •Итератор-адаптер
- •Создание просмотра
- •Реализация итератора-адаптера для zip_view.
- •Диагностика
- •Отладка ошибок
- •Трассировка инстанцирования
- •Исправленный пример:
- •Форматы сообщений об ошибках
- •Блок «with»
- •Устранение параметров шаблона по умолчанию
- •Глубокий typedef
- •Инструменты
- •Несколько компиляторов
- •(Статические Утверждения)
- •Формат:
- •Формат:
- •Индивидуальные сообщения утверждений
- •Настройка предиката:
- •(Генерирование встроенных сообщений)
- •Формат:
- •Выбор стратегии:
- •Тип печати
- •Кросс этапность компиляции/выполнения
- •Печать типов:
- •Тип посещения:
- •Выбор реализаций
- •Специализация шаблонов классов
- •Тег диспетчеризации
- •Выбор структуры
- •Композиция классов
- •Указатели на функцию
- •Ослабление типизации
- •Пример:
- •Обобщение:
- •Динамический полиморфизм
- •Автоматизация
- •Сохранение интерфейса
- •Рекуррентный шаблон
- •Формат:
- •Генерирование функций
- •Управление разрешением перегрузки
- •Явное управление множеством перегрузки
- •Документация mpl Последовательности
- •Концепции
- •(Прямая последовательность)
- •(Двунаправленная Последовательность)
- •(Последовательность произвольного доступа)
- •(Расширенная последовательность)
- •(Расширенная последовательность начала)
- •(Расширенная последовательность конца)
- •(Ассоциативная последовательность)
- •(Расширенная ассоциативная последовательность)
- •(Обертка интегральной последовательности )
- •(Переменная последовательность)
- •Представления
- •Метафункции (Внутренние)
- •Итераторы
- •Концепции
- •(Прямой итератор)
- •(Двунаправленный итератор)
- •(Итератор произвольного доступа)
- •Метафункции
- •Алгоритмы
- •Концепции
- •(Инсертер: механизм вставок)
- •Инсертеры (инсертер: механизм вставок)
- •Итеративные алгоритмы
- •Запрашиваемые алгоритмы
- •Преобразования
- •Метафункции
- •Концепции Метафункция
- •Метафункциональный класс
- •Лямбда выражения
- •Заполнители
- •Тэг диспетчеризированные метафункции
- •Числовые метафункции
- •Тривиальные метафункции
Наследование
Как правило, непронумерованная форма любой последовательности получена из соответствующей пронумерованной формы, или имеет общий базовый класс, который обеспечивает выполнение последовательности.
Например, mpl::vector мог бы быть определен так:
namespace boost {
namespace mpl {
struct void_; // "no argument" marker
// primary template declaration
template <class T0 = void_, class T1 = void_, etc....>
struct vector;
// specializations
template<>
struct vector<> : vector0<> {};
template<class T0>
struct vector<T0> : vector1<T0> {};
template<class T0, class T1>
struct vector<T0,T1> : vector2<T0,T1> {};
template<class T0, class T1, class T2>
struct vector<T0,T1,T2> : vector3<T0,T1,T2> {};
//etc...
}
}
Интегральные обертки последовательности так же являются производными из эквивалентных основных последовательностей типа.
Все встроенные последовательности MPL разработаны так, чтобы почти любой подкласс функционировал как эквивалентная последовательность типа.
Наследование - сильный способ обеспечить новый интерфейс, или только новое имя, существующей семье последовательностей.
Например, библиотека Boost Python обеспечивает следующую последовательность типа:
namespace boost {
namespace python {
template <class T0 = mpl::void_, ... class T4 = mpl::void_>
struct bases : mpl::vector<T0, T1, T2, T3, T4> {};
}
}
Так, с поомщью наследования можно создавать свои последовательности:
struct signed_integers
: mpl::vector<signed char, short, int, long> {};
На некоторых компиляторах, используя signed_integers вместо основного вектора может резко улучшить эффективность метапрограммы.
Создание последовательности
Причиной создания собственных последовательностей обычно является вопрос эффективности и оптимизации приложения. В то время как последовательности MPL хорошо оптимизированы для использования общего назначения, а специализированная версия может дать прирост скорости.
Для этого примера напишем последовательность произвольного доступа ограниченного размера, эта реализация будет очень близкой к реализации mpl::vector для тех компиляторов, которые не поддерживают конструкцию typeof.
Реализация:
Выбрать представление (внутреннее состояние класса), для этого требуется 3 элемента (ограничимся этим количеством) для трех типов, которые оно может содержать в последовательности:
struct none {}; // tag type to denote no element
template <class T0 = none, class T1 = none, class T2 = none>
struct tiny
{
typedef tiny type;
typedef T0 t0;
typedef T1 t1;
typedef T2 t2;
//...
};
Вложенным типом будет тип самой последовательности: «самовозвращающаяся метафункция». Все последовательности MPL делают что-то подобное – очень удобное решение. Например: если необходимо возвратить последовательность из какой-либо метафункции, то можно просто выполнить операцию наследования конкретной последовательности и продвинуть ее внутренний элемент «::type». Кроме того, когда одна ветвь в eval_if (один операнд) должна возвращать последовательность, то не нужно создавать дополнительную оберктку mpl::identity для него, т.о., можно делать выбор более простым способом(S - наша последовательность):
// pop the front element off S, unless it is empty
typedef mpl::eval_if<
mpl::empty<S>
, mpl::identity<S>
, mpl::pop_front<S>
>::type r1;
// likewise
typedef mpl::eval_if<
mpl::empty<S>
, S // when invoked, S returns S
, mpl::pop_front<S>
>::type r2;
Вложенные синонимы элементов последовательности: t0, t1, t2, позволяют удобно организовывать взаимодействие с данной последовательностью:
template <class Tiny>
struct manipulate_tiny;
template <class T0, class T1, class T2>
struct manipulate_tiny<tiny<T0, T1, T2>>
{
// T0 is known
};
Так, вложенные типы, позволяют упрощать код.
template <class Tiny>
struct manipulate_tiny
{
// what's T0?
typedef typename Tiny::t0 t0;
};
Пока типами элементов является структура none (маркер отсутствия элемента), такая обертка еще не явялется последовательностью, хоть и предоставляет удобный интерфейс для проведения до трех элементов.
Одно из оснонвых требований к последовательности - возврат итератора, для работы метафункция mpl::begin, mpl::end, потому необходимо добавить итератор в представление. Поскольку итератор произвольного доступа может перемещаться в обоих направлениях, то он будет иметь доступ ко всем элементам последовательности. Самый простой способ реализовать это, является внедрение всей последовательности в сам итератор. Такие внеднерения характерны для MPL итераторов, которым передается вся иличасть последовательности, которую они обойти(итераторам для контейнеров типа mpl::list необходимо передавать лишь оставшуюся часть списка –доступную часть последовательности ).
