- •Вычисления значений
- •Пример:
- •Вычисления типов
- •Преимущества мета подхода:
- •Польза использования mpl:
- •Числовая метафункция
- •Свойства
- •Метаданные
- •Специализация
- •Первичный шаблон:
- •Инстанцирование:
- •Метафункции
- •Полиморфизм
- •Возможности свойств:
- •Организация свойств в Boost:
- •Пример:
- •Типовые ассоциации
- •Альтернатива:
- •Метафункции Продвижение (пересылка) метафункций
- •Класс метафункции
- •Формат:
- •Числовые
- •Пример:
- •Нульарные
- •Метрический анализ (Анализ размерностей)
- •Метрики
- •Величины
- •Сложение и вычитание
- •Умножение
- •Класс метафункции
- •Деление
- •Пример:
- •Метафункции высшего порядка (Каскады вложенных вызовов)
- •Использование apply:
- •Заполнители
- •Безымянный заполнитель:
- •Определение выражений с заполнителями
- •Лямбда (Лямбда метафункции/выражения)
- •Частичное приложение метафункции
- •Лямбда и Шаблоны Неметафункции
- •Обертки
- •Выбор типа
- •Ленивый Выбор Типа
- •Логические Операторы
- •Целочисленные обертки
- •Составные Операторы
- •Операторы с булевым значением:
- •Операторы для сравнения значений:
- •Операторы для интегральных значений:
- •Побитовые операторы:
- •Арифметические операторы:
- •Целочисленная «стенография»
- •Интегральные последовательности
- •Формат:
- •Последовательности
- •Концепции
- •Итераторы
- •Двунаправленные
- •Произвольные
- •Последовательности
- •Двунаправленные
- •Произвольные
- •Расширенные
- •Ассоциативные
- •Требования
- •Расширения
- •Расширенные ассоциативные последовательности
- •Алгоритмы и последовательности
- •Итераторы
- •Равенство
- •Операции Внутренние операции с последовательностей
- •Наследование
- •Создание последовательности
- •Реализация:
- •Создание итератора
- •Преимущества полной специализации перед частичной:
- •Добавление расширения
- •Алгоритмы
- •Абстракция:
- •Stl алгоритмы
- •Детали правильного использования stl:
- •Mpl алгоритмы
- •Различия stl и mpl алгоритмов:
- •Пример:
- •Вставки
- •Пример 1:
- •Пример 2:
- •Пример 3:
- •Фундамент алгоритмов
- •Пример:
- •Запрашиваемые алгоритмы
- •Последовательности (Алгоритмы, создающие последовательности)
- •Синонимы функциональных алгоритмов:
- •Создание алгоритма
- •Итераторы «Просмотр» и итераторы-адаптеры
- •Концепция просмотра
- •Применение просмотра Сравнения значений элементов последовательности:
- •Объединение множественных (мульти-) последовательностей
- •Упрощение 1
- •Упрощение 2 (создание просмотра)
- •Уход от ненужного вычисления
- •Выборочная обработка элемента
- •Итератор-адаптер
- •Создание просмотра
- •Реализация итератора-адаптера для zip_view.
- •Диагностика
- •Отладка ошибок
- •Трассировка инстанцирования
- •Исправленный пример:
- •Форматы сообщений об ошибках
- •Блок «with»
- •Устранение параметров шаблона по умолчанию
- •Глубокий typedef
- •Инструменты
- •Несколько компиляторов
- •(Статические Утверждения)
- •Формат:
- •Формат:
- •Индивидуальные сообщения утверждений
- •Настройка предиката:
- •(Генерирование встроенных сообщений)
- •Формат:
- •Выбор стратегии:
- •Тип печати
- •Кросс этапность компиляции/выполнения
- •Печать типов:
- •Тип посещения:
- •Выбор реализаций
- •Специализация шаблонов классов
- •Тег диспетчеризации
- •Выбор структуры
- •Композиция классов
- •Указатели на функцию
- •Ослабление типизации
- •Пример:
- •Обобщение:
- •Динамический полиморфизм
- •Автоматизация
- •Сохранение интерфейса
- •Рекуррентный шаблон
- •Формат:
- •Генерирование функций
- •Управление разрешением перегрузки
- •Явное управление множеством перегрузки
- •Документация mpl Последовательности
- •Концепции
- •(Прямая последовательность)
- •(Двунаправленная Последовательность)
- •(Последовательность произвольного доступа)
- •(Расширенная последовательность)
- •(Расширенная последовательность начала)
- •(Расширенная последовательность конца)
- •(Ассоциативная последовательность)
- •(Расширенная ассоциативная последовательность)
- •(Обертка интегральной последовательности )
- •(Переменная последовательность)
- •Представления
- •Метафункции (Внутренние)
- •Итераторы
- •Концепции
- •(Прямой итератор)
- •(Двунаправленный итератор)
- •(Итератор произвольного доступа)
- •Метафункции
- •Алгоритмы
- •Концепции
- •(Инсертер: механизм вставок)
- •Инсертеры (инсертер: механизм вставок)
- •Итеративные алгоритмы
- •Запрашиваемые алгоритмы
- •Преобразования
- •Метафункции
- •Концепции Метафункция
- •Метафункциональный класс
- •Лямбда выражения
- •Заполнители
- •Тэг диспетчеризированные метафункции
- •Числовые метафункции
- •Тривиальные метафункции
(Генерирование встроенных сообщений)
MPL содержит макрос для создания персонализированных сообщений, что не требует написания отдельного класса-предиката и контроля за однозначным его именованием.
Формат:
BOOST_MPL_ASSERT_MSG(condition, message, types);
Этот макрос подходит как для отображения интегральных константных выражений, так и типов парметров функции.
BOOST_MPL_ASSERT_MSG(N::value >= 0, FACTORIAL_of_NEGATIVE_NUMBER, (N));
Диагностика (GCC):
foo.cpp:31: error: conversion from 'mpl_::failed
****************(factorial<mpl_::int_<-5>
>::FACTORIAL_of_NEGATIVE_NUMBER::****************)
(mpl_::int_<-5>)' to non-scalar type 'mpl_::assert<false>'
requested.
Список параметров «(N)», мог бы быть пустым «()»:
foo.cpp:31: error: conversion from 'mpl_::failed
****************(factorial<mpl_::int_<-5>
>::FACTORIAL_of_NEGATIVE_NUMBER::****************)
()' to non-scalar type 'mpl_::assert<false>'
requested.
BOOST_MPL_ASSERT_MSG требует некоторой осторожности, так как типы аргументов, используется в списке параметров функции, а также некоторые типы мы могли бы иметь особое значение в этом контексте. Например, пустой параметр (void) будет исключен из диагностики, так как int F (void) - это int F (). Кроме того, тип пустого параметра (void) может быть использован только один раз в спсике параметров функции: int F (void,void) – недопустимый синтаксис. Кроме того, массив и тип функции интерпретируются как указатель и указатель на функцию, соответственно:
int f(int x[2], char* (long))
что эквивалентно:
int f(int *x, char* (*)(long))
Если точные типы, которые должны быть выведены в макросе заранее неизвестны, то можно применить следующую форму (поддерживает до 4 типов):
BOOST_MPL_ASSERT_MSG(condition, message, (types<types >));
Например, можно добавить следующее утверждение в метафункцию факториала, проверяющее, что все интегральные константные обретки являются классами:
BOOST_MPL_ASSERT_MSG
(
boost::is_class<N>::value,
NOT_an_INTEGRAL_CONSTANT_WRAPPER,
(types<N>)
);
При передаче, например, типа «void», диагностика будет следующей (MSVC7.1):
foo.cpp(34) : error C2664: 'mpl_::assertion_failed' : cannot
convert parameter 1 from 'mpl_::failed
****************(__thiscall
factorial<N>::NOT_an_INTEGRAL_CONSTANT_WRAPPER::*
*************** )(mpl_::assert_::types<T1>)
' to 'mpl_::assert<false>::type'
with
[
N=void,
T1=void
]
Распознавание до 4 типов аргументов более корректно работает в тех компиляторах, где диагностика не отображает шаблонные параметры по умолчанию. В противном случае, сообщение может иметь следующий вид (Intel C++ 8.0 учитывает шаблонные параметры по умолчанию):
foo.cpp(31): error: no instance of function template
"mpl_::assertion_failed" matches the argument list
argument types are: (mpl_::failed ****************
(factorial<void>::NOT_an_INTEGRAL_CONSTANT_WRAPPER::
****************)(mpl_::assert_::types<void, mpl_::na,
mpl_::na, mpl_::na>))
BOOST_MPL_ASSERT_MSG(
^
detected during instantiation of class "factorial<N>
[with N=void]" at line 37
В то время как настроенные предикаты, используемые в BOOST_MPL_ASSERT должны быть расположены в пространстве имен макроса, то сообщения генерируемые из BOOST_MPL_ASSERT_MSG выступает как квалифицированные элементы той области видимости, где утверждение было выдано (в данном случае факториал <void>). Потому, компиляторы которые поддерживают чтение глубоких переопределений посредством typedef, способны делать вставки типов нечитаемых расширений в диагностику.
Например, при инстанцировании:
mpl::transform<mpl::vector<void>, factorial<mpl::_>>
Диагнотика (Intel C++ 8.0):
foo.cpp(34): error: no instance of function template
"mpl_::assertion_failed" matches the argument list
argument types are: (mpl_::failed
****************(factorial<boost::mpl::bind1<
boost::mpl::quote1<factorial, boost::mpl::void_>,
boost::mpl::lambda<mpl_::_,
boost::mpl::void_>::result_>::apply<
boost::mpl::bind1<factorial<mpl_::_>,
mpl_::_2>::apply<boost::mpl::aux::fold_impl<1,
boost::mpl::begin<boost::mpl::vector<void, mpl_::na,
mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na,
mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na,
mpl_::na, mpl_::na, mpl_::na,
...four similar long lines omitted...
mpl_::na>::t1>::NOT_an_INTEGRAL_CONSTANT_WRAPPER::
****************)(mpl_::assert_::types<boost::mpl::bind1<
line continued...
...five similar lines omitted...
BOOST_MPL_ASSERT_MSG(
^
Вывод такой информации явно снижает читабельность диагностики.
