Программирование >>  Операторы преобразования типа 

1 ... 88 89 90 [ 91 ] 92 93 94 ... 239


2. Другая функция реализуется для всех категорий итераторов, имеющих специальную реализацию, не унаследованную от одной из категорий итераторов. Пример:

fooO для двунаправленных итераторов

template <class BlIterator>

void foo (BiIterator beg. BiIterator end.

std::bid1rectional iterator tag)

Версия для итераторов произвольного доступа могла бы, например, использовать возможности, не поддерживаемые двунаправленными итераторами. Благодаря иерархической структуре тегов итераторов (см. с. 287) можно предоставить одну реализацию для нескольких категорий итераторов.

Выбор реализации для функции distance

В следующем примере демонстрируется описагпгая методика выбора реализации в зависимости от типа итератора. Мы рассмотрим реализацию вспомогательной функции distanceO, возвращающей расстояние между двумя позициями итераторов и их элементов (см. с. 267). Реализация для итераторов произвольного доступа сводится к простому использованию оператора -. Для остальных категорий итераторов возвращается количество операций + + , необходимых для достижения конца интервала.

Унифицированная реализация функции distanceO template <class Iterator>

typename std::iterator traits<Iterator>::difference type distance (Iterator posl. Iterator pos2)

return distance (posl, pos2.

std::1terator traits<Iterator> ::iterator category()):

Реализация функции distanceO для итераторов произвольного доступа template <class RaIterator>

typename std;:iterator tralts<RaIterator>::difference type distance (Ralterator posl, Ralterator pos2. std::random access iterator tag)

return pos2 - posl:

Реализация функции distanceO для итераторов ввода. прямых и двунаправленных итераторов template <class InIterator>



typename std::iterator tra1ts<lnlterator>::d1fference type distance (Inlterator posl. Inlterator pos2. std::input iterator tag)

typename std::iterator traits<InIterator>::difference type d: for Cd=0; posl != pos2; ++posl, ++d) {

return d:

Тип разности итераторов используется как тип возвращаемого значения. Обратите внимание: во второй версии указан тег итераторов ввода, поэтому реализация автоматически используется прямыми и двунаправленными итераторами, теги которых являются производными от inputJterator tag.

Пользовательские итераторы

Давайте напишем свой итератор. Как упоминалось в предыдущем разделе, для этого нужно предоставить варианты трактовки пользовательского итератора, что можно сделать двумя способами.

О Передача пяти необходимых типов в общей структуре iterator traits (см. с. 288).

О Предоставление (частичной) специализации структуры iterator traits.

Для использования первого способа в стандартную библиотеку С++ включен специальный базовый класс iteratoro, содержащий определения типов. Вам остается лип1ь передать нужные типы:

class Mylterator : public std::iterator <std:;bidirect1onal iterator tag.

type. std::pt rd i ff t. type*. type&> {

Первый параметр шаблона определяет категорию итератора, второй - тин элемента, третий - тип разности, четвертый - тип указателя, а пятый - тип ссылки. Последние три аргумента не обязательны, по умолчанию им присваиваются значения ptrdiff t, type* и typeBk. Во многих случаях достаточно следующего определения:

class Mylterator

: public std::iterator <std::bidirect1onal iterator tag. type> {

Б прежних версиях STL вместо типа iterator использовались вспомогательные типы input iterator, output iterator, forward iterator, bidirectionaMterator и random access iterator.



Ниже показано, как написать пользовательский итератор на примере итератора вставки для ассоциативных контейнеров. В отличие от итераторов вставки стандартной библиотеки С++ (см. с. 275) наш итератор не использует позицию вставки.

Реализация класса итератора выглядит так:

iter/assoiter.hpp #1nclude <1terator>

/* Шаблон итератора вставки для ассоциативных контейнеров */

template <class Contalner> class asso insert iterator : public std: :iterator <std: ;outputJterator tag.

void, void. void. void>

protected:

Containers container; Контейнер, в который вставпяются элементы

public: Конструктор

explicit asso insert iterator (Containers с) : container(c) (

Оператор присваивания

- вставляет значение в контейнер

asso i nsertj terator<Contai ner>&

operator= (const typename Container::value type& value) { container.insert(value); return *th1s;

Разыменование - пустая операция, которая возвращает сам итератор asso 1nsert iterator<Container>& operator* О { return *this;

Увеличение - пустая операция, которая возвращает сам итератор asso insert 1terator<Container>& operator++ О { return *this;

asso insert iterator<Container>& operator++ (int) { return *this;

/* Вспомогательная функция для создания итератора вставки template <clas5 Container>



1 ... 88 89 90 [ 91 ] 92 93 94 ... 239

© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика