Упражнение 9.28. Напишите функцию, получающую контейнер forward_list и два дополнительных аргумента типа string. Функция должна находить первую строку и вставлять вторую непосредственно после первой. Если первая строка не найдена, то вставьте вторую строку в конец списка.

<p>9.3.5. Изменение размеров контейнера</p>

Для изменения размера контейнера, за исключением массива, можно использовать функцию resize(), представленную в табл. 9.9. Если текущий размер больше затребованного, элементы удаляются с конца контейнера; если текущий размер меньше нового, элементы добавляются в конец контейнера:

list ilist(10, 42); // 10 целых чисел со значением 42

ilist.resize(15);        // добавляет 5 элементов со значением 0

                         // в конец списка ilist

ilist.resize(25, -1);    // добавляет 10 элементов со значением -1

                         // в конец списка ilist

ilist.resize(5);         // удаляет 20 элементов от конца списка ilist

Функция resize() получает необязательный аргумент — значение элемента, используемое для инициализации всех добавляемых элементов. Если этот аргумент отсутствует, добавленные элементы инициализируются значением по умолчанию (см. раздел 3.3.1). Если контейнер хранит элементы типа класса и функция resize() добавляет элементы, то либо следует предоставить инициализатор, либо тип элемента должен иметь стандартный конструктор.

Таблица 9.9. Функции размера последовательного контейнера

За исключением массива
c.resize(n)Измените размеры контейнера с так, чтобы у него было n элементов. Если n < c.size(), то лишние элементы отбрасываются. Если следует добавить новые элементы, они инициализируются значением по умолчанию
с.resize(n,t)Измените размеры контейнера с так, чтобы у него было n элементов. Все добавляемые элементы получат значение t

Если функция resize() сокращает контейнер, то итераторы, ссылки и указатели на удаленные элементы окажутся некорректными; выполнение функции resize() для контейнеров vector, string и deque может сделать некорректными все итераторы, указатели и ссылки.

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

Упражнение 9.29. Если контейнер vec содержит 25 элементов, то что делает выражение vec.resize(100)? Что если затем последует вызов vec.resize(10)?

Упражнение 9.30. Какие ограничения (если они есть) налагает использование функции resize() с одиночным аргументом, имеющим тип элемента?

<p><image l:href="#reader.png"/>9.3.6. Некоторые операции с контейнерами делают итераторы недопустимыми</p>

Функции, добавляющие и удаляющие элементы из контейнера, могут сделать некорректными указатели, ссылки или итераторы на его элементы. Некорректными считаются те указатели, ссылки и итераторы, которые больше не указывают на элемент. Использование некорректного указателя, ссылки или итератора является серьезной ошибкой, последствия которой, вероятно, будут схожи с использованием неинициализированного указателя (см. раздел 2.3.2, стр. 89).

После операции добавления элементов в контейнер возможно следующее.

• Итераторы, указатели и ссылки на элементы вектора или строки становятся недопустимыми после повторного резервирования пространства контейнера. Если повторного резервирования не было, ссылки на элементы перед позицией вставки остаются допустимыми, а на элементы после позиции вставки — нет.

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

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

• У контейнеров list и forward_list все остальные итераторы, ссылки и указатели (включая итераторы после конца и перед началом) остаются допустимыми.

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

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