Чтение онлайн

ЖАНРЫ

РУКОВОДСТВО ПО СТАНДАРТНОЙ БИБЛИОТЕКЕ ШАБЛОНОВ (STL)

Менг Ли

Шрифт:

template ‹class Key, class T, class Compare, class Allocator›

bool operator‹(const multimap‹Key, T, Compare, Allocator›& x, const multimap‹Key, T, Compare, Allocator›& y);

iterator - двунаправленный итератор, указывающий на value_type. Точный тип зависит от реализации и определяется в Allocator.

const_iterator - постоянный двунаправленный итератор, указывающий на value_type. Точный тип зависит от реализации и определяется в Allocator. Гарантируется, что имеется конструктор для const_iterator из iterator.

size_type - целочисленный тип без

знака. Точный тип зависит от реализации и определяется в Allocator.

difference_type - целочисленный тип со знаком. Точный тип зависит от реализации и определяется в Allocator.

ИТЕРАТОРЫ ПОТОКОВ

Чтобы шаблоны алгоритмов могли работать непосредственно с потоками ввода-вывода, предусмотрены соответствующие шаблонные классы, подобные итераторам. Например,

partial_sum_copy(istream_iterator‹double›(cin), istream_iterator‹double›, ostream_iterator‹double›(cout, "\n"));

читает файл, содержащий числа с плавающей запятой, из cin и печатает частичные суммы в cout.

Итератор входного потока (Istream Iterator)

istream_iterator‹T› читает (используя operator››) последовательные элементы из входного потока, для которого он был создан. После своего создания итератор каждый раз при использовании ++ читает и сохраняет значение T. Если достигнут конец потока (operator void* в потоке возвращает false), итератор становится равным значению end-of-stream (конец-потока). Конструктор без параметров istream_iterator всегда создаёт итераторный объект конца потокового ввода, являющийся единственым законным итератором, который следует использовать для конечного условия. Результат operator* для конца потока не определён, а для любого другого значения итератора возвращается const T&.

Невозможно записывать что-либо с использованием входных итераторов. Основная особенность входных итераторов - тот факт, что операторы ++ не сохраняют равенства, то есть i==j не гарантирует вообще, что ++i==++j. Каждый раз, когда ++ используется, читается новое значение. Практическое следствие этого факта - то, что входные итераторы могут использоваться только для однопроходных алгоритмов, что действительно имеет здравый смысл, так как многопроходным алгоритмам всегда более соответствует использование структур данных в оперативной памяти.

Два итератора конец-потока всегда равны. Итератор конец-потока не равен не-конец-потока итератору. Два не-конец-потока итератора равны, когда они созданы из того же самого потока.

template ‹class T, class Distance = ptrdiff_t›

class istream_iterator: public input_iterator‹T, Distance› {

 friend bool operator==(const istream_iterator‹T, Distance›& x, const istream_iterator‹T, Distance›& y);

public:

 istream_iterator;

 istream_iterator(istream& s);

 istream_iterator(const istream_iterator‹T, Distance›& x);

 ~istream_iterator;

 const T& operator* const;

 istream_iterator‹T, Distance›& operator++;

 istream_iterator‹T, Distance› operator++(int);

};

template ‹class T, class Distance›

bool operator==(const istream_iterator‹T, Distance›& x, const istream_iterator‹T, Distance›& y);

Итератор

выходного потока (Ostream Iterator)

istream_iterator‹T› записывает (используя operator‹‹) последовательные элементы в выходной поток, из которого он был создан. Если он был создан с параметром конструктора char*, эта строка, называемая строкой разделителя (delimiter string), записывается в поток после того, как записывается каждое T. Невозможно с помощью выходного итератора получить значение. Его единственное использование - выходной итератор в ситуациях, подобных нижеследующему:

while (first != last) *result++ = *first++;

ostream_iterator определён как:

template ‹class T›

class ostream_iterator: public output_iterator {

public:

 ostream_iterator(ostream& s);

 ostream_iterator(ostream& s, const char* delimiter);

 ostream_iterator(const ostream_iterator‹T›& x);

 ~ostream_iterator;

 ostream_iterator‹T›& operator=(const T& value);

 ostream_iterator‹T›& operator*;

 ostream_iterator‹T›& operator++;

 ostream_iterator‹T›& operator++(int);

};

АЛГОРИТМЫ

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

Для некоторых алгоритмов предусмотрены и оперативные и копирующие версии. Решение, включать ли копирующую версию, было обычно основано на рассмотрении сложности. Когда стоимость выполнения операции доминирует над стоимостью копии, копирующая версия не включена. Например, sort_copy не включена, так как стоимость сортировки намного значительнее, и пользователи могли бы также делать copy перед sort. Когда такая версия предусмотрена для какого-то алгоритма algorithm, он называется algorithm _copy . Алгоритмы, которые берут предикаты, оканчиваются суффиксом _if (который следует за суффиксом _copy).

Класс Predicate используется всякий раз, когда алгоритм ожидает функциональный объект, при применении которого к результату разыменования соответствующего итератора возвращается значение, обратимое в bool. Другими словами, если алгоритм берёт Predicate pred как свой параметр и first как свой параметр итератора, он должен работать правильно в конструкции if (pred(*first)) {…}. Предполагается, что функциональный объект pred не применяет какую-либо непостоянную функцию для разыменованного итератора.

Поделиться с друзьями: