- •Вычисления значений
- •Пример:
- •Вычисления типов
- •Преимущества мета подхода:
- •Польза использования mpl:
- •Числовая метафункция
- •Свойства
- •Метаданные
- •Специализация
- •Первичный шаблон:
- •Инстанцирование:
- •Метафункции
- •Полиморфизм
- •Возможности свойств:
- •Организация свойств в Boost:
- •Пример:
- •Типовые ассоциации
- •Альтернатива:
- •Метафункции Продвижение (пересылка) метафункций
- •Класс метафункции
- •Формат:
- •Числовые
- •Пример:
- •Нульарные
- •Метрический анализ (Анализ размерностей)
- •Метрики
- •Величины
- •Сложение и вычитание
- •Умножение
- •Класс метафункции
- •Деление
- •Пример:
- •Метафункции высшего порядка (Каскады вложенных вызовов)
- •Использование apply:
- •Заполнители
- •Безымянный заполнитель:
- •Определение выражений с заполнителями
- •Лямбда (Лямбда метафункции/выражения)
- •Частичное приложение метафункции
- •Лямбда и Шаблоны Неметафункции
- •Обертки
- •Выбор типа
- •Ленивый Выбор Типа
- •Логические Операторы
- •Целочисленные обертки
- •Составные Операторы
- •Операторы с булевым значением:
- •Операторы для сравнения значений:
- •Операторы для интегральных значений:
- •Побитовые операторы:
- •Арифметические операторы:
- •Целочисленная «стенография»
- •Интегральные последовательности
- •Формат:
- •Последовательности
- •Концепции
- •Итераторы
- •Двунаправленные
- •Произвольные
- •Последовательности
- •Двунаправленные
- •Произвольные
- •Расширенные
- •Ассоциативные
- •Требования
- •Расширения
- •Расширенные ассоциативные последовательности
- •Алгоритмы и последовательности
- •Итераторы
- •Равенство
- •Операции Внутренние операции с последовательностей
- •Наследование
- •Создание последовательности
- •Реализация:
- •Создание итератора
- •Преимущества полной специализации перед частичной:
- •Добавление расширения
- •Алгоритмы
- •Абстракция:
- •Stl алгоритмы
- •Детали правильного использования stl:
- •Mpl алгоритмы
- •Различия stl и mpl алгоритмов:
- •Пример:
- •Вставки
- •Пример 1:
- •Пример 2:
- •Пример 3:
- •Фундамент алгоритмов
- •Пример:
- •Запрашиваемые алгоритмы
- •Последовательности (Алгоритмы, создающие последовательности)
- •Синонимы функциональных алгоритмов:
- •Создание алгоритма
- •Итераторы «Просмотр» и итераторы-адаптеры
- •Концепция просмотра
- •Применение просмотра Сравнения значений элементов последовательности:
- •Объединение множественных (мульти-) последовательностей
- •Упрощение 1
- •Упрощение 2 (создание просмотра)
- •Уход от ненужного вычисления
- •Выборочная обработка элемента
- •Итератор-адаптер
- •Создание просмотра
- •Реализация итератора-адаптера для zip_view.
- •Диагностика
- •Отладка ошибок
- •Трассировка инстанцирования
- •Исправленный пример:
- •Форматы сообщений об ошибках
- •Блок «with»
- •Устранение параметров шаблона по умолчанию
- •Глубокий typedef
- •Инструменты
- •Несколько компиляторов
- •(Статические Утверждения)
- •Формат:
- •Формат:
- •Индивидуальные сообщения утверждений
- •Настройка предиката:
- •(Генерирование встроенных сообщений)
- •Формат:
- •Выбор стратегии:
- •Тип печати
- •Кросс этапность компиляции/выполнения
- •Печать типов:
- •Тип посещения:
- •Выбор реализаций
- •Специализация шаблонов классов
- •Тег диспетчеризации
- •Выбор структуры
- •Композиция классов
- •Указатели на функцию
- •Ослабление типизации
- •Пример:
- •Обобщение:
- •Динамический полиморфизм
- •Автоматизация
- •Сохранение интерфейса
- •Рекуррентный шаблон
- •Формат:
- •Генерирование функций
- •Управление разрешением перегрузки
- •Явное управление множеством перегрузки
- •Документация mpl Последовательности
- •Концепции
- •(Прямая последовательность)
- •(Двунаправленная Последовательность)
- •(Последовательность произвольного доступа)
- •(Расширенная последовательность)
- •(Расширенная последовательность начала)
- •(Расширенная последовательность конца)
- •(Ассоциативная последовательность)
- •(Расширенная ассоциативная последовательность)
- •(Обертка интегральной последовательности )
- •(Переменная последовательность)
- •Представления
- •Метафункции (Внутренние)
- •Итераторы
- •Концепции
- •(Прямой итератор)
- •(Двунаправленный итератор)
- •(Итератор произвольного доступа)
- •Метафункции
- •Алгоритмы
- •Концепции
- •(Инсертер: механизм вставок)
- •Инсертеры (инсертер: механизм вставок)
- •Итеративные алгоритмы
- •Запрашиваемые алгоритмы
- •Преобразования
- •Метафункции
- •Концепции Метафункция
- •Метафункциональный класс
- •Лямбда выражения
- •Заполнители
- •Тэг диспетчеризированные метафункции
- •Числовые метафункции
- •Тривиальные метафункции
Инструменты
Самыми трудноразборчивыми ошибками при диагностике шаблонов являются глубоко вложенные шаблонные инстанцирования.
Правило:
Чем раньше обнаружена ошибка, тем с меньшими усилиями ее можно исправить.
Масштабные сообщения об ошибках времени компиляции гораздо лучше тихого исполнения программы с возможным падением от срабатывания assert утверждений.
Причиной того, почему сообщения об ошибках в шаблоннах часто не дают представления о сути и расположении фактической проблемы, состоит в том, что они происходят слишком поздно, когда инстанцирование достигло глубин деталей реализации библиотеки. Поскольку у самого компилятора нет представления о контексте (домене) библиотеки, он неспособен обнаружить ошибки использования интерфейсов библиотеки и вовремя сообщать о них с точки зрения абстракций библиотеки.
Например, мы могли бы попытаться скомпилировать:
#include <algorithm>
#include <list>
int main()
{
std::list<int> x;
std::sort(x.begin(), x.end());
}
В идеале компилятор должен сообщать о проблеме в момент фактической ошибки программы, а также предоставлять информацию о абстракции итераторов, как в этом случае:
main.cpp(7) : std::sort requires random access iterators, but
std::list<int>::iterator is only a bidirectional iterator
В MSVC7.1 отчет выглядит следующим образом:
C:\Program Files \Microsoft Visual Studio .NET 2003\Vc7 \include\
algorithm(1795) : error C2784:
'reverse_iterator<_RanIt>::difference_type std::operator -(const
std::reverse_iterator<_RanIt> &,const
std::reverse_iterator<_RanIt> &)' : could not deduce template
argument for 'const std::reverse_iterator<_RanIt> &' from
'std::list<_Ty>::iterator'
with
[
_Ty=int
]
continued...
Сообщается об ошибке в некотором операторе стандартной библиотеке в заголовке <algorithm>, вместо того, чтобы сообщить об ошибке в теле функции main(), где она фактически произошла. Причина: проблема сокрыта из-за появления std::reverse_iterator, который не имеет никакого очевидного отношения к написанному коду. Даже использование оператора, который «намекает» на потребность в итераторах произвольного доступа, непосредственно не связано с тем, что программист пытался на самом деле сделать. Если бы несоответствие между итертором std::list <int>::iterator и требованием std::sort в итерторе произвольного доступа было обнаружено ранее (идеально в точке вызова std::sort), то компилятор смог бы сообщить о проблеме максимально точно.
Проблема плохих сообщений в ошибках – это не вина компилятора, фактически, это происходит из-за ограничения языка C++. Если сигнатуры обычных функций четко указывают типы допустимых аргументов, то для обобщенных функций такой ясности нет. При этом, у авторов библиотеки есть механизмы, как ограничить ущерб, наносимый ошибкой. Эти подходы позволяют генерировать диагностику заранее и в большей степени контролировать содержание сообщений об ошибках.
Несколько компиляторов
Советы:
Использовать несколько различных компиляторов в отладочных целях.
Использование пост-процессорной обработки, с помощью следующих приложений (TextFilt (http://textfilt.sourceforge.net) или STLFilt (http://www.bdsoft.com/tools/stlfilt.html). Их основные возможности включают в себя автоматическую элизию аргументов по умолчанию из специализаций известных шаблонов, и typedef замены std::string и std::wstring.
Например, TextFilt может преобразовать следующие сообщения:
example.cc:21: conversion from 'double' to non-scalar type
'map<vector<basic_string<char, string_char_traits<char>,
__default_alloc_template<true, 0> >,
allocator<basic_string<char, string_char_traits<char>,
__default_alloc_template<true, 0> > > >, set<basic_string<char,
string_char_traits<char>, _ _default_alloc_template<true, 0> >,
less<basic_string<char, string_char_traits<char>,
__default_alloc_template<true, 0> > >,
allocator<basic_string<char, string_char_traits<char>,
__default_alloc_template<true, 0> > > >,
less<vector<basic_string<char, string_char_traits<char>,
__default_alloc_template<true, 0> >,
allocator<basic_string<char, string_char_traits<char>,
__default_alloc_template<true, 0> > > > >,
allocator<set<basic_string<char, string_char_traits<char>,
__default_alloc_template<true, 0> >, less<basic_string<char,
string_char_traits<char>, _ _default_alloc_template<true, 0> > >,
allocator<basic_string<char, string_char_traits<char>,
__default_alloc_template<true, 0> > > > > >' requested
в следующее:
example.cc:21: conversion from 'double' to non-scalar type
'map<vector<string>,set<string>>' requested
Редактировкани сообщений об ошибка в среде GCC:
Есть два варианта для изменения порядка сообщение GCC:
hdr: LD1: переносит сообщение об ошибке в начало следа трассировки;
hdr: LD2: подобен hdr:LD1, но добавляет копию последней строке трассировки (не-шаблонный код, который привел к инициированию) только после сообщения об ошибке.
Обертки для выражений и идентификация:
Прблемными местами для фильтрации сообщений являются составные типы и выражения – с вложенными элементами. STLFilt включает в себя мета опцию, которая форматирует сообщения метапрограммных компонентов. Даже с пропуском шаблонных параметров по умолчанию и отключенными переопределениями typdef, STLFilt может помочь в разборе сообщения:
example.cc:21: conversion from 'double' to non-scalar type
'map<
vector<
basic_string<
char, string_char_traits<char>
, __default_alloc_template<true, 0>
>, allocator<
basic_string<
char, string_char_traits<char>
, __default_alloc_template<true, 0>
>
>
>, set<
basic_string<
char, string_char_traits<char>
, __default_alloc_template<true, 0>
>, less<
basic_string<
char, string_char_traits<char>
, __default_alloc_template<true, 0>
>
>, allocator<
basic_string<
char, string_char_traits<char>
' __default_alloc_template<true, 0>
>
>
>, less<
...12 lines omitted...
>, allocator<
...16 lines omitted...
>
>' requested
Хоть сообщение все еще огромно, но зато стало намного более читаемым: его первые несколько столбцов позволяют понять, что типом является map, состоящий из vector <string> и set <string>.
Настройка параметров командной строки в www.bdsoft.com/tools/stlfiltopts.html.
Static Assertions
