Выбрать главу

vector string svec2( svec );

list int ilist2( ilist ) ;

Каждый контейнер поддерживает полный набор операций сравнения: равенство, неравенство, меньше, больше, меньше или равно, больше или равно. Сопоставляются попарно все элементы контейнера. Если они равны и размеры контейнеров одинаковы, то эти контейнеры равны; в противном случае – не равны. Результат операций “больше” или “меньше” определяется сравнением первых двух неравных элементов. Вот что печатает программа, сравнивающая пять векторов:

ivecclass="underline" 1 3 5 7 9 12

ivec2: 0 1 1 2 3 5 8 13

ivec3: 1 3 9

ivec4: 1 3 5 7

ivec5: 2 4

// первый неравный элемент: 1, О

// ivecl больше чем ivec2

ivecl ivec2 //false

ivec2 ivecl //true

// первый неравный элемент: 5, 9

ivecl ivec3 //true

// все элементы равны, но ivec4 содержит меньше элементов

// следовательно, ivec4 меньше, чем ivecl

ivecl ivec4 //false

// первый неравный элемент: 1, 2

ivecl ivec5 //true

ivecl == ivecl //true

ivecl == ivec4 //false

ivecl != ivec4 //true

ivecl ivec2 //true

ivec3 ivecl //true

ivec5 ivec2 //true

Существуют три ограничения на тип элементов контейнера (практически это касается только пользовательских классов). Для должны быть определены:

* операция “равно”;

* операция “меньше” (все операции сравнения контейнеров, о которых говорилось выше, используют только эти две операции сравнения);

* значение по умолчанию (для класса это означает наличие конструктора по умолчанию).

Все предопределенные типы данных, включая указатели и классы из стандартной библиотеки С++ удовлетворяют этим требованиям.

Упражнение 6.5

Объясните, что делает данная программа:

#include string

#include vector

#include iostream

#int main()

{

vectorstring svec;

svec.reserve( 1024 );

string text_word;

while ( cin text_word )

svec.push_back( text_word );

svec.resize( svec.size()+svec.size()/2 );

// ...

}

Упражнение 6.6

Может ли емкость контейнера быть меньше его размера? Желательно ли, чтобы емкость была равна размеру: изначально или после вставки элемента? Почему?

Упражнение 6.7

Если программа из упражнения 6.5 прочитает 256 слов, то какова наиболее вероятная емкость контейнера после изменения размера? А если она считает 512 слов? 1000? 1048?

Упражнение 6.8

Какие из данных классов не могут храниться в векторе:

(a)

class cl1 {

public:

c11( int=0 );

bool operator==();

bool operator!=();

bool operator=();

bool operator();

// ...

};

(b)

class c12 {

public:

c12( int=0 );

bool operator!=();

bool operator=();

// ...

};

(с)

class c13 {

public:

int ival;

};

(d)

class c14 {

public:

c14( int, int=0 );

bool operator==();

bool operator!=();

// ...

}

6.5. Итераторы

Итератор предоставляет обобщенный способ перебора элементов любого контейнера – как последовательного, так и ассоциативного. Пусть iter является итератором для какого-либо контейнера. Тогда

++iter;

перемещает итератор так, что он указывает на следующий элемент контейнера, а

*iter;

разыменовывает итератор, возвращая элемент, на который он указывает.

Все контейнеры имеют функции-члены begin() и end().

* begin() возвращает итератор, указывающий на первый элемент контейнера.

* end() возвращает итератор, указывающий на элемент, следующий за последним в контейнере.

Чтобы перебрать все элементы контейнера, нужно написать:

for ( iter = container. begin();

iter != container.end(); ++iter )

do_something_with_element( *iter );

Объявление итератора выглядит слишком сложным. Вот определение пары итераторов вектора типа string:

// vectorstring vec;

vectorstring::iterator iter = vec.begin();

vectorstring::iterator iter_end = vec.end();

В классе vector для определения iterator используется typedef. Синтаксис

vectorstring::iterator

ссылается на iterator, определенный с помощью typedef внутри класса vector, содержащего элементы типа string.

Для того чтобы напечатать все элементы вектора, нужно написать:

for( ; iter != iter_end; ++iter )

cout *iter '\n';