list::iterator iter;

// count имеет тип difference_type, определенный классом vector

vector::difference_type count;

В этих объявлениях оператор области видимости (см. раздел 1.2) позволяет указать, что используется тип-член iterator класса list и тип-член difference_type, определенный классом vector, соответственно.

Упражнения раздела 9.2.2

Упражнение 9.7. Какой тип следует использовать в качестве индекса для вектора целых чисел?

Упражнение 9.8. Какой тип следует использовать для чтения элементов в списке строк?

<p><image l:href="#reader.png"/>9.2.3. Функции-члены <code>begin()</code> и <code>end()</code></p>

Функции-члены begin() и end() (см. раздел 3.4.1) возвращают итераторы на первый и следующий после последнего элементы контейнера соответственно. Эти итераторы, как правило, используют при создании диапазона итераторов, охватывающего все элементы контейнера.

Как показано в табл. 9.2, есть несколько версий этих функций: имена которых начинаются с буквы r возвращают реверсивные итераторы (рассматриваются в разделе 10.4.3), а с буквы c — возвращают константную версию соответствующего итератора:

list a = {"Milton", "Shakespeare", "Austen"};

auto it1 = a.begin();  // list::iterator

auto it2 = a.rbegin(); // list::reverse_iterator

auto it3 = a.cbegin(); // list::const_iterator

auto it4 = a.crbegin();// list::const_reverse_iterator

Функции, имена которых не начинаются с буквы c, перегружены. Таким образом, фактически есть две функции-члена begin(). Одна является константной (см. раздел 7.1.2) и возвращает тип const_iterator контейнера. Вторая не константна и возвращает тип iterator контейнера. Аналогично для функций rbegin(), end() и rend(). При вызове такой функции-члена для неконстантного объекта используется версия, возвращающая тип iterator. Константная версия итераторов будет получена только при вызове этих функций для константного объекта. Подобно указателям и ссылкам на константу, итератор типа iterator можно преобразовать в соответствующий итератор типа const_iterator, но не наоборот.

Версии этих функций, имена которых не начинаются с буквы с, были введены согласно новому стандарту для обеспечения использования ключевого слова auto с функциями begin() и end() (см. раздел 2.5.2). Прежде не было никакого иного выхода, кроме как явно указать необходимый тип итератора:

// тип указан явно

list::iterator it5 = a.begin();

list::const_iterator it6 = a.begin();

// iterator или const_iterator в зависимости от типа а

auto it7 = a.begin();  // const_iterator только если a константа

auto it8 = a.cbegin(); // it8 - const_iterator

Когда с функциями begin() или end() используется ключевое слово auto, тип возвращаемого итератора зависит от типа контейнера. То, как предполагается использовать итератор, несущественно. Версии c позволяют получать итератор типа const_iterator независимо от типа контейнера.

Когда доступ на запись не нужен, используйте версии cbegin() и cend().

Упражнения раздела 9.2.3

Упражнение 9.9. В чем разница между функциями begin() и cbegin()?

Упражнение 9.10. Каковы типы следующих четырех объектов?

vector v1;

const vector v2;

auto it1 = v1.begin(), it2 = v2.begin();

auto it3 = v1.cbegin(), it4 = v2.cbegin();

<p><image l:href="#reader.png"/>9.2.4. Определение и инициализация контейнера</p>

Каждый контейнерный тип определяет стандартный конструктор (см. раздел 7.1.4). За исключением контейнера array стандартный конструктор создает пустой контейнер определенного типа. Также за исключением контейнера array другие конструкторы получают аргументы, которые определяют размер контейнера и исходные значения его элементов.

Инициализация контейнера как копии другого контейнера

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

Таблица 9.3. Определение и инициализация контейнера

Перейти на страницу:

Похожие книги