Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
template_metaprogramming_ru.docx
Скачиваний:
12
Добавлен:
01.07.2025
Размер:
774 Кб
Скачать
☆

Создание просмотра

Т. к. большая часть «интеллекта» последовательностей просмотров заключено в их итераторах-адаптерах, потому большая часть работы по реализации просмотра уделяется именно реализации итератора-адаптера.

Реализация итератора-адаптера для zip_view.

Т. к. zip_view работает на последовательности входных последовательностей, естественно, что его итератор-адаптер должен работать на последовательности итераторов входных последовательностей.

Установим последовательность в качетсве параметра итератору zip_iterator :

template <class IteratorSeq> struct zip_iterator;

Пусть zip_iterator всегда будет прямым итератором.

Единственные требования, которым должен соответствовать прямой итератор:

  • Обеспечить операцию разыменования с mpl::deref;

  • Обеспечить операцию инкрементации с mpl::next;

Чтобы разыменовать zip_iterator, мы должны разыменовать каждый ее итератор-компонент и упаковывать результаты в последовательность. Т.к. по умолчанию mpl::deref вызывает свой аргумент как метафункцию, zip_iterator принимает следующий вид:

template <class IteratorSeq>

struct zip_iterator

{

typedef mpl::forward_iterator_tag category;

typedef typename mpl::transform< // Формирует новую последовательность раскрытых элементов.

IteratorSeq,

mpl::deref<_1>

>::type type;

};

Аналогично, инкрементация zip_iterator’а требует инкрементации каждого ее итератора-компонента:

namespace boost {

namespace mpl {

// specialize next<...> for zip_iterator

template <class IteratorSeq>

struct next<zip_iterator<IteratorSeq>>

{

typedef zip_iterator<

typename transform<

IteratorSeq,

next<_1>

>::type

> type;

};

}

}

Так, каждый базоый итератор будет перемещен на 1 позицию в своей последовательности, что сформирует новую последовательность базоыйх итераторов, которая передается итератору-адаптеру в качестве аргумента.

Единственный оставшийся элемент, который мы могли бы добавить к телу zip_iterator для удобства, является элемент «::base», который обеспечивает доступ к адаптированным итераторам (базовым). В итерторе-адаптере для единственного адаптируемого итератора, «::base» является одним итератором;

Реализуем «::base» для последовательности базовых итераторов:

typedef IteratorSeq base;

Создадим последовательность, которая использует zip_iterator. Фактически, можно создать zip_view из iterator_range:

template <class Sequences>

struct zip_view

: mpl::iterator_range<

zip_iterator<

typename mpl::transform_view<

Sequences,

mpl::begin<_1>

>::type

>,

zip_iterator<

typename mpl::transform_view<

Sequences,

mpl::end<_1>

>::type

>

>

{};

Диагностика

Поскольку метапрограммы C++ выполняются во время компиляции, вопрос отладки - отдельная проблема. Не существует отладчика, который позволял бы проверять процесс выполнения метапрограммы, устанавливать точки останова, исследовать данные, такой вид отладки потребовал бы интерактивного контроля внутреннего состояния компилятора, всё что оствется – это изучать сообщения об ошибках, в случае, если компиляция была прервана.

Текущее диагностирование шаблонов в C++ затруднительное дело, т.к. нет четкого описания конкретной проблемы и сообщения об ошибках содержа много такой информации, которая к ошибке вообще не имеет дела.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]