- •Вычисления значений
- •Пример:
- •Вычисления типов
- •Преимущества мета подхода:
- •Польза использования mpl:
- •Числовая метафункция
- •Свойства
- •Метаданные
- •Специализация
- •Первичный шаблон:
- •Инстанцирование:
- •Метафункции
- •Полиморфизм
- •Возможности свойств:
- •Организация свойств в Boost:
- •Пример:
- •Типовые ассоциации
- •Альтернатива:
- •Метафункции Продвижение (пересылка) метафункций
- •Класс метафункции
- •Формат:
- •Числовые
- •Пример:
- •Нульарные
- •Метрический анализ (Анализ размерностей)
- •Метрики
- •Величины
- •Сложение и вычитание
- •Умножение
- •Класс метафункции
- •Деление
- •Пример:
- •Метафункции высшего порядка (Каскады вложенных вызовов)
- •Использование apply:
- •Заполнители
- •Безымянный заполнитель:
- •Определение выражений с заполнителями
- •Лямбда (Лямбда метафункции/выражения)
- •Частичное приложение метафункции
- •Лямбда и Шаблоны Неметафункции
- •Обертки
- •Выбор типа
- •Ленивый Выбор Типа
- •Логические Операторы
- •Целочисленные обертки
- •Составные Операторы
- •Операторы с булевым значением:
- •Операторы для сравнения значений:
- •Операторы для интегральных значений:
- •Побитовые операторы:
- •Арифметические операторы:
- •Целочисленная «стенография»
- •Интегральные последовательности
- •Формат:
- •Последовательности
- •Концепции
- •Итераторы
- •Двунаправленные
- •Произвольные
- •Последовательности
- •Двунаправленные
- •Произвольные
- •Расширенные
- •Ассоциативные
- •Требования
- •Расширения
- •Расширенные ассоциативные последовательности
- •Алгоритмы и последовательности
- •Итераторы
- •Равенство
- •Операции Внутренние операции с последовательностей
- •Наследование
- •Создание последовательности
- •Реализация:
- •Создание итератора
- •Преимущества полной специализации перед частичной:
- •Добавление расширения
- •Алгоритмы
- •Абстракция:
- •Stl алгоритмы
- •Детали правильного использования stl:
- •Mpl алгоритмы
- •Различия stl и mpl алгоритмов:
- •Пример:
- •Вставки
- •Пример 1:
- •Пример 2:
- •Пример 3:
- •Фундамент алгоритмов
- •Пример:
- •Запрашиваемые алгоритмы
- •Последовательности (Алгоритмы, создающие последовательности)
- •Синонимы функциональных алгоритмов:
- •Создание алгоритма
- •Итераторы «Просмотр» и итераторы-адаптеры
- •Концепция просмотра
- •Применение просмотра Сравнения значений элементов последовательности:
- •Объединение множественных (мульти-) последовательностей
- •Упрощение 1
- •Упрощение 2 (создание просмотра)
- •Уход от ненужного вычисления
- •Выборочная обработка элемента
- •Итератор-адаптер
- •Создание просмотра
- •Реализация итератора-адаптера для zip_view.
- •Диагностика
- •Отладка ошибок
- •Трассировка инстанцирования
- •Исправленный пример:
- •Форматы сообщений об ошибках
- •Блок «with»
- •Устранение параметров шаблона по умолчанию
- •Глубокий typedef
- •Инструменты
- •Несколько компиляторов
- •(Статические Утверждения)
- •Формат:
- •Формат:
- •Индивидуальные сообщения утверждений
- •Настройка предиката:
- •(Генерирование встроенных сообщений)
- •Формат:
- •Выбор стратегии:
- •Тип печати
- •Кросс этапность компиляции/выполнения
- •Печать типов:
- •Тип посещения:
- •Выбор реализаций
- •Специализация шаблонов классов
- •Тег диспетчеризации
- •Выбор структуры
- •Композиция классов
- •Указатели на функцию
- •Ослабление типизации
- •Пример:
- •Обобщение:
- •Динамический полиморфизм
- •Автоматизация
- •Сохранение интерфейса
- •Рекуррентный шаблон
- •Формат:
- •Генерирование функций
- •Управление разрешением перегрузки
- •Явное управление множеством перегрузки
- •Документация mpl Последовательности
- •Концепции
- •(Прямая последовательность)
- •(Двунаправленная Последовательность)
- •(Последовательность произвольного доступа)
- •(Расширенная последовательность)
- •(Расширенная последовательность начала)
- •(Расширенная последовательность конца)
- •(Ассоциативная последовательность)
- •(Расширенная ассоциативная последовательность)
- •(Обертка интегральной последовательности )
- •(Переменная последовательность)
- •Представления
- •Метафункции (Внутренние)
- •Итераторы
- •Концепции
- •(Прямой итератор)
- •(Двунаправленный итератор)
- •(Итератор произвольного доступа)
- •Метафункции
- •Алгоритмы
- •Концепции
- •(Инсертер: механизм вставок)
- •Инсертеры (инсертер: механизм вставок)
- •Итеративные алгоритмы
- •Запрашиваемые алгоритмы
- •Преобразования
- •Метафункции
- •Концепции Метафункция
- •Метафункциональный класс
- •Лямбда выражения
- •Заполнители
- •Тэг диспетчеризированные метафункции
- •Числовые метафункции
- •Тривиальные метафункции
Автоматизация
С помощью шаблонов можно обобщить процесс введения новый реализаций настроек:
class screensaver
{
private:
struct customization
{
virtual ~customization() {}
virtual float operator()(float) const = 0;
};
template <class F> // a wrapper for an F
struct wrapper : customization
{
explicit wrapper(F f)
: f(f) {} // store an F
float operator()(float x) const
{
return this->f(x); // delegate to stored F
}
private:
F f;
};
public:
template <class F>
explicit screensaver(F const& f)
: get_seed(new wrapper<F>(f))
{}
//...
private:
std::auto_ptr<customization> get_seed;
//...
};
Теперь можно передавать любые указатели на функции или функторы в конструктор класса screensaver, до тех пор, пока аргументом вызова и результатом выступает тип float.
Сохранение интерфейса
При таком подходе процесс ослабления типовой информации является результатом превращения разнообразных типов с общим интерфейсом в один тип, конкретизируя данный интерфейс. Так, конкретная реализация сохранялась в auto_ptr <customization>, который является элементом класса screensaver. Сам auto_ptr не вызываемый, в только хранящися в нем указатель и сам вызов мог бы быть расположен в теле данного класса. Лучши решением будет вынести данную обертку за пределы тела класса и организовать ее отдельным классом float_function, чтобы позволит использовать ее в любом проекте.
Сам класс «заставки» избавляется от деталей реализации и становится более выразительным:
class screensaver
{
public:
explicit screensaver(float_function f)
: get_seed(f)
{}
pixel_map next_screen()
{
float center_pixel_brightness = ...;
float seed = this->get_seed(center_pixel_brightness);
//...
}
private:
float_function get_seed;
//...
};
Рефакторинга позволяет реализовать для общего интерфейса всех функторов возможность создания копий. Чтобы сделать возможным копирование и хранение объектов класса float_function в теле класса screensaver необходимо применить, рассмотренные выше, механизмы виртуализации и создания оболочек для реализаций, для использования их при копировании объектов.
Виртуализация позволит создавать множество реализаций единого интерфейса настроек.
Оболочка для типов – обобщенный вариант реализации интерфейса и клонирования, которая наследует данный интерфейс и позволяет хранить указатели на функции или функторы.
Механизм клонирования будет использован в конструкторе копии.
class float_function
{
private:
// Абстрактный интерфейс для настроек класса screensaver.
struct impl
{
virtual ~impl() {}
virtual impl* clone() const = 0;
virtual float operator()(float) const = 0;
};
// Обобщенный вариант реализации и клонирования:
template <class F>
struct wrapper : impl
{
explicit wrapper(F const& f) : f(f) {}
impl* clone() const
{
return new wrapper<F>(this->f); // delegate
}
float operator()(float x) const
{
return f(x); // delegate
}
private:
F f;
};
public:
// Конструктор-преобразования позволит инициализировать состояние
// переданным типом.
template <class F>
float_function(F const& f) : pimpl(new wrapper<F>(f)) {}
// Конструктор-копии использует элементы оболочки.
float_function(float_function const& rhs)
: pimpl(rhs.pimpl->clone()){}
float_function& operator=(float_function const& rhs)
{
this->pimpl.reset(rhs.pimpl->clone()); // создаем клона и меняем состояние.
return *this;
}
float operator()(float x) const
{
return (*this->pimpl)(x);
}
private:
std::auto_ptr<impl> pimpl;
};
Данный класс позволяет «захватывать» функциональность любой вызываемой сущности, которая принимает и возвращает тип float. Это основной паттерн библиотеки Boost Function Library, представленный в TR1, где его обобщенная версия поддерживать произвольные аргументы и возвращаемые типы. Так, вся реализация float_function может быть заменена на вариант из Boost следующим образом:
typedef boost::function<float (float x)> float_function;
Аргументом шаблона является тип функции, которым будет специфицирован отдельный функтор.
