- •Вычисления значений
- •Пример:
- •Вычисления типов
- •Преимущества мета подхода:
- •Польза использования mpl:
- •Числовая метафункция
- •Свойства
- •Метаданные
- •Специализация
- •Первичный шаблон:
- •Инстанцирование:
- •Метафункции
- •Полиморфизм
- •Возможности свойств:
- •Организация свойств в Boost:
- •Пример:
- •Типовые ассоциации
- •Альтернатива:
- •Метафункции Продвижение (пересылка) метафункций
- •Класс метафункции
- •Формат:
- •Числовые
- •Пример:
- •Нульарные
- •Метрический анализ (Анализ размерностей)
- •Метрики
- •Величины
- •Сложение и вычитание
- •Умножение
- •Класс метафункции
- •Деление
- •Пример:
- •Метафункции высшего порядка (Каскады вложенных вызовов)
- •Использование apply:
- •Заполнители
- •Безымянный заполнитель:
- •Определение выражений с заполнителями
- •Лямбда (Лямбда метафункции/выражения)
- •Частичное приложение метафункции
- •Лямбда и Шаблоны Неметафункции
- •Обертки
- •Выбор типа
- •Ленивый Выбор Типа
- •Логические Операторы
- •Целочисленные обертки
- •Составные Операторы
- •Операторы с булевым значением:
- •Операторы для сравнения значений:
- •Операторы для интегральных значений:
- •Побитовые операторы:
- •Арифметические операторы:
- •Целочисленная «стенография»
- •Интегральные последовательности
- •Формат:
- •Последовательности
- •Концепции
- •Итераторы
- •Двунаправленные
- •Произвольные
- •Последовательности
- •Двунаправленные
- •Произвольные
- •Расширенные
- •Ассоциативные
- •Требования
- •Расширения
- •Расширенные ассоциативные последовательности
- •Алгоритмы и последовательности
- •Итераторы
- •Равенство
- •Операции Внутренние операции с последовательностей
- •Наследование
- •Создание последовательности
- •Реализация:
- •Создание итератора
- •Преимущества полной специализации перед частичной:
- •Добавление расширения
- •Алгоритмы
- •Абстракция:
- •Stl алгоритмы
- •Детали правильного использования stl:
- •Mpl алгоритмы
- •Различия stl и mpl алгоритмов:
- •Пример:
- •Вставки
- •Пример 1:
- •Пример 2:
- •Пример 3:
- •Фундамент алгоритмов
- •Пример:
- •Запрашиваемые алгоритмы
- •Последовательности (Алгоритмы, создающие последовательности)
- •Синонимы функциональных алгоритмов:
- •Создание алгоритма
- •Итераторы «Просмотр» и итераторы-адаптеры
- •Концепция просмотра
- •Применение просмотра Сравнения значений элементов последовательности:
- •Объединение множественных (мульти-) последовательностей
- •Упрощение 1
- •Упрощение 2 (создание просмотра)
- •Уход от ненужного вычисления
- •Выборочная обработка элемента
- •Итератор-адаптер
- •Создание просмотра
- •Реализация итератора-адаптера для zip_view.
- •Диагностика
- •Отладка ошибок
- •Трассировка инстанцирования
- •Исправленный пример:
- •Форматы сообщений об ошибках
- •Блок «with»
- •Устранение параметров шаблона по умолчанию
- •Глубокий typedef
- •Инструменты
- •Несколько компиляторов
- •(Статические Утверждения)
- •Формат:
- •Формат:
- •Индивидуальные сообщения утверждений
- •Настройка предиката:
- •(Генерирование встроенных сообщений)
- •Формат:
- •Выбор стратегии:
- •Тип печати
- •Кросс этапность компиляции/выполнения
- •Печать типов:
- •Тип посещения:
- •Выбор реализаций
- •Специализация шаблонов классов
- •Тег диспетчеризации
- •Выбор структуры
- •Композиция классов
- •Указатели на функцию
- •Ослабление типизации
- •Пример:
- •Обобщение:
- •Динамический полиморфизм
- •Автоматизация
- •Сохранение интерфейса
- •Рекуррентный шаблон
- •Формат:
- •Генерирование функций
- •Управление разрешением перегрузки
- •Явное управление множеством перегрузки
- •Документация mpl Последовательности
- •Концепции
- •(Прямая последовательность)
- •(Двунаправленная Последовательность)
- •(Последовательность произвольного доступа)
- •(Расширенная последовательность)
- •(Расширенная последовательность начала)
- •(Расширенная последовательность конца)
- •(Ассоциативная последовательность)
- •(Расширенная ассоциативная последовательность)
- •(Обертка интегральной последовательности )
- •(Переменная последовательность)
- •Представления
- •Метафункции (Внутренние)
- •Итераторы
- •Концепции
- •(Прямой итератор)
- •(Двунаправленный итератор)
- •(Итератор произвольного доступа)
- •Метафункции
- •Алгоритмы
- •Концепции
- •(Инсертер: механизм вставок)
- •Инсертеры (инсертер: механизм вставок)
- •Итеративные алгоритмы
- •Запрашиваемые алгоритмы
- •Преобразования
- •Метафункции
- •Концепции Метафункция
- •Метафункциональный класс
- •Лямбда выражения
- •Заполнители
- •Тэг диспетчеризированные метафункции
- •Числовые метафункции
- •Тривиальные метафункции
Пример:
Реализуем прототипирование алгоритма для работы некоторого изображения (заставки), поведение котрого необходимо настраивать динамически. Алгоритм для создания изображение на экране является довольно сложным, но он легок в настройке: изменяя простую числовую функцию, которая вызывается один раз за период (кадр) в ядре алгоритма, можно генерировать различные заготовки для изображения. Расточительно делать целую заставку (весь класс) изображения шаблоном для использования подобного просто механзима параметризации, вместо этого оптимальнее будет использовать указатель на функцию преобразования:
typedef float (*floatfunc)(float);
class screensaver
{
public:
explicit screensaver(floatfunc get_seed)
: get_seed(get_seed)
{}
pixel_map next_screen() // main algorithm
{
float center_pixel_brightness = ...;
float seed = this->get_seed(center_pixel_brightness);
//complex computation using seed...
}
private:
floatfunc get_seed;
//other members...
};
Если возникает необходимость добавления новых настроек. Например, новые настройки требуют создания вектора для 128 целочисленных параметров, которые изменяются при каждом вызове next_screen ().
Обобщение:
Добавим в класс screensaver элемент std::vector<int>, а также измененим список параметров next_screen, добавив дополнительного аргумент в функцию настройки:
class screensaver
{
pixel_map next_screen()
{
float center_pixel_brightness = ...;
float seed = this->get_seed(center_pixel_brightness, state);
//...
}
private:
std::vector<int> state;
float (*get_seed)(float, std::vector<int>& s);
//...
};
Такая модификация требует корректировки списка параметров и реализации самой функции преобразования, а в случае появления новых настроек, нужно будет вновь переписывать код реализаций.
Решение: дополнительный уровень абстракции. Если заменить механизм настройки посредством указателя на функцию – отдельным классом (вложенным/вынесенным – pimpl, что позволит даже не перекомпилировать тело класса), который сделает состояние настройки деталью внутренней реализации, тогда класс screensaver будет работать только с объектом класса настройки, изменения в котором не требуют модификации реализации основного алгоритма:
class screensaver
{
public:
struct customization // Интерфейс вложенной структуры настроек.
{
virtual ~customization() {}
virtual float operator()(float) const = 0;
};
explicit screensaver(std::auto_ptr<customization> c)
: get_seed(c)
{}
pixel_map next_screen()
{
float center_pixel_brightness = ...;
float seed = (*this->get_seed)(center_pixel_brightness);
//...
}
private:
std::auto_ptr<customization> get_seed;
//...
};
Динамический полиморфизм
Теперь можно написать класс наследник, который будет реализовывать интерфейс настроек, например содержит дополнительное состояние в качестве элемента, а также осуществляет сами настройки в теле оператора ():
struct hypnotic : screensaver::customization
{
float operator()(float) const
{
//...use this->state...
}
std::vector<int> state;
};
Если, теперь, понадобятся такие настройки, которые не нуждаются в векторе состояний, то можно выполнить просто другую реализацию посредством наследования (обертка для указателя на функцию настроек):
struct funwrapper : screensaver::customization
{
funwrapper(floatfunc pf)
: pf(pf) {}
float operator()(float x) const
{
return this->pf(x);
}
floatfunc pf; // stored function pointer
};
Так, достигается сокрытие информации о конкретном типе настроек в теле конкретной реализации единого интерфейса натсроек.
