- •Вычисления значений
- •Пример:
- •Вычисления типов
- •Преимущества мета подхода:
- •Польза использования mpl:
- •Числовая метафункция
- •Свойства
- •Метаданные
- •Специализация
- •Первичный шаблон:
- •Инстанцирование:
- •Метафункции
- •Полиморфизм
- •Возможности свойств:
- •Организация свойств в Boost:
- •Пример:
- •Типовые ассоциации
- •Альтернатива:
- •Метафункции Продвижение (пересылка) метафункций
- •Класс метафункции
- •Формат:
- •Числовые
- •Пример:
- •Нульарные
- •Метрический анализ (Анализ размерностей)
- •Метрики
- •Величины
- •Сложение и вычитание
- •Умножение
- •Класс метафункции
- •Деление
- •Пример:
- •Метафункции высшего порядка (Каскады вложенных вызовов)
- •Использование apply:
- •Заполнители
- •Безымянный заполнитель:
- •Определение выражений с заполнителями
- •Лямбда (Лямбда метафункции/выражения)
- •Частичное приложение метафункции
- •Лямбда и Шаблоны Неметафункции
- •Обертки
- •Выбор типа
- •Ленивый Выбор Типа
- •Логические Операторы
- •Целочисленные обертки
- •Составные Операторы
- •Операторы с булевым значением:
- •Операторы для сравнения значений:
- •Операторы для интегральных значений:
- •Побитовые операторы:
- •Арифметические операторы:
- •Целочисленная «стенография»
- •Интегральные последовательности
- •Формат:
- •Последовательности
- •Концепции
- •Итераторы
- •Двунаправленные
- •Произвольные
- •Последовательности
- •Двунаправленные
- •Произвольные
- •Расширенные
- •Ассоциативные
- •Требования
- •Расширения
- •Расширенные ассоциативные последовательности
- •Алгоритмы и последовательности
- •Итераторы
- •Равенство
- •Операции Внутренние операции с последовательностей
- •Наследование
- •Создание последовательности
- •Реализация:
- •Создание итератора
- •Преимущества полной специализации перед частичной:
- •Добавление расширения
- •Алгоритмы
- •Абстракция:
- •Stl алгоритмы
- •Детали правильного использования stl:
- •Mpl алгоритмы
- •Различия stl и mpl алгоритмов:
- •Пример:
- •Вставки
- •Пример 1:
- •Пример 2:
- •Пример 3:
- •Фундамент алгоритмов
- •Пример:
- •Запрашиваемые алгоритмы
- •Последовательности (Алгоритмы, создающие последовательности)
- •Синонимы функциональных алгоритмов:
- •Создание алгоритма
- •Итераторы «Просмотр» и итераторы-адаптеры
- •Концепция просмотра
- •Применение просмотра Сравнения значений элементов последовательности:
- •Объединение множественных (мульти-) последовательностей
- •Упрощение 1
- •Упрощение 2 (создание просмотра)
- •Уход от ненужного вычисления
- •Выборочная обработка элемента
- •Итератор-адаптер
- •Создание просмотра
- •Реализация итератора-адаптера для zip_view.
- •Диагностика
- •Отладка ошибок
- •Трассировка инстанцирования
- •Исправленный пример:
- •Форматы сообщений об ошибках
- •Блок «with»
- •Устранение параметров шаблона по умолчанию
- •Глубокий typedef
- •Инструменты
- •Несколько компиляторов
- •(Статические Утверждения)
- •Формат:
- •Формат:
- •Индивидуальные сообщения утверждений
- •Настройка предиката:
- •(Генерирование встроенных сообщений)
- •Формат:
- •Выбор стратегии:
- •Тип печати
- •Кросс этапность компиляции/выполнения
- •Печать типов:
- •Тип посещения:
- •Выбор реализаций
- •Специализация шаблонов классов
- •Тег диспетчеризации
- •Выбор структуры
- •Композиция классов
- •Указатели на функцию
- •Ослабление типизации
- •Пример:
- •Обобщение:
- •Динамический полиморфизм
- •Автоматизация
- •Сохранение интерфейса
- •Рекуррентный шаблон
- •Формат:
- •Генерирование функций
- •Управление разрешением перегрузки
- •Явное управление множеством перегрузки
- •Документация mpl Последовательности
- •Концепции
- •(Прямая последовательность)
- •(Двунаправленная Последовательность)
- •(Последовательность произвольного доступа)
- •(Расширенная последовательность)
- •(Расширенная последовательность начала)
- •(Расширенная последовательность конца)
- •(Ассоциативная последовательность)
- •(Расширенная ассоциативная последовательность)
- •(Обертка интегральной последовательности )
- •(Переменная последовательность)
- •Представления
- •Метафункции (Внутренние)
- •Итераторы
- •Концепции
- •(Прямой итератор)
- •(Двунаправленный итератор)
- •(Итератор произвольного доступа)
- •Метафункции
- •Алгоритмы
- •Концепции
- •(Инсертер: механизм вставок)
- •Инсертеры (инсертер: механизм вставок)
- •Итеративные алгоритмы
- •Запрашиваемые алгоритмы
- •Преобразования
- •Метафункции
- •Концепции Метафункция
- •Метафункциональный класс
- •Лямбда выражения
- •Заполнители
- •Тэг диспетчеризированные метафункции
- •Числовые метафункции
- •Тривиальные метафункции
Исправленный пример:
struct nil {};
template <class H, class T = nil>
struct node
{
typedef H head; typedef T tail;
};
template <class S>
struct total_size
{
typedef typename total_size<
typename S::tail
>::type tail_size;
typedef boost::mpl::int_<
sizeof(S::head)
+ tail_size::value
> type;
};
// Добавление частичной специализации для завершения рекурсии:
template <class H>
struct total_size<node<H, nil>>
{
typedef H tail_size;
typedef boost::mpl::int_<sizeof(H)> type;
};
int main(int argc, char* argv[])
{
typedef node<char, node<int, node<float, node<String>>>> l;
auto size = total_size<l>::type::value;
cout << size << endl;
return 0;
}
Форматы сообщений об ошибках
Несмотря на различие компиляторов, есть некоторые общности в их сообщениях об ошибках.
Исследуем диагностику, произведенную тремя различными компиляторами для следующего примера:
#include <map>
#include <list>
#include <iterator>
#include <string>
#include <algorithm>
using namespace std;
void copy_list_map(list<string> & l, map<string, string>& m)
{
std::copy(l.begin(), l.end(), std::back_inserter(m));
}
Несмотря на простоту кода, некоторые компиляторы выдают для него очень масштабные сообщения об ошибках (MSVC6):
C:\PROGRA~1\MICROS~4\VC98\INCLUDE\xutility(19) : error C2679:
binary '=' : no operator defined which takes a right-hand operand
of type 'class std::basic_string<char,struct std::char_traits<
char>,class std::allocator<char> >' (or there is no acceptable
conversion)
foo.cpp(9) : see reference to function template
instantiation 'class std::back_insert_iterator<class std::
map<class std::basic_string<char, struct std::char_traits<
char>,class std::allocator<char> >,class std::basic_string<
char,struct std::char_traits<char>,class std::allocator<char
> >,struct std::less<class std::basic_string<char,struct std
::char_traits<char>,class std::allocator<char> > >,class std
::allocator<class std::basic_string<char,struct std::
char_traits<char>,class std::allocator<char> > > > > __cdecl
std::copy(class std::list<class std::basic_string<char,
struct std::char_traits<char>,class std::allocator<char> >,
class std::allocator<class std::basic_string<char,struct std
::char_traits<char>,class std::allocator<char> > > >::
iterator,class std::list<class std::basic_string<char,struct
std::char_traits<char>,class std::allocator<char> >,class
std::allocator<class std::basic_string<char,struct std::
char_traits<char>,class std::allocator<char> > > >::iterator
,class std::back_insert_iterator<class std::map<class std::
basic_string<char,struct std::char_traits<char>,class std::
allocator<char> >,class std::basic_string<char,struct std::
char_traits<char>,class std::allocator<char> >,struct std::
less<class std::basic_string<char,struct std::char_traits<
char>,class std::allocator<char> > >,class std::allocator<
class std::basic_string<char,struct std::char_traits<char>,
class std::allocator<char> > > > >)' being compiled
message continues...
typedef
Длинные типы, наподобии следующего
class std::basic_string<char, struct std::char_traits<char>,class std::allocator<char>>
часто повторяются в выводах, наршуая общую читабельность сообщений. Если выполнить замену данного «внутреннего» типа на переопределенный string, то сообщение об ошибке примет следующий вид:
C:\PROGRA~1\MICROS~4\VC98\INCLUDE\xutility(19) : error C2679:
binary '=' : no operator defined which takes a right-hand operand
of type 'std::string' (or there is no acceptable conversion)
foo.cpp(9) : see reference to function template instantiation
'class std::back_insert_iterator<class std::map<std::string,
std::string,struct std::less<std::string>,class
std::allocator<std::string> > > __cdecl std::copy(class
std::list<std::string,class std::allocator<std::string>
>::iterator,class std::list<std::string,class std::allocator<
std::string> >::iterator,class std::back_insert_iterator<
class std::map<std::string,std::string,struct std::
less<std::string>,class std::allocator<std::string> > >)'
being compiled
Так сообщение выглядит боллее читабельным. Последние версии GCC делаеют такие преобразования к синонимам для всех переопределенных типов автоматически (в MSVC10 такие замены также происходят):
...continued messages
/usr/include/c++/3.2/bits/stl_algobase.h:228: no match for '
std::back_insert_iterator<std::map<std::string, std::string,
std::less<std::string>, std::allocator<std::pair<const
std::string, std::string> > > >& = std::basic_string<char,
std::char_traits<char>, std::allocator<char> >&' operator
messages continue...
При этом GCC не сделал замену правого операнда в в операции присваивания и в этом есть смысл.
