82. Используйте подходящие идиомы для реального уменьшения емкости контейнера и удаления элементов
82. Используйте подходящие идиомы для реального уменьшения емкости контейнера и удаления элементов
Резюме
Для того чтобы действительно избавиться от излишней емкости контейнера, воспользуйтесь трюком с использованием обмена, а для реального удаления элементов из контейнера — идиомой erase-remove.
Обсуждение
Некоторые контейнеры (например, vector, string, deque) могут иметь "лишнюю" емкость, которая больше не будет использоваться. Хотя стандартная библиотека C++ не предоставляет гарантированного способа для удаления излишней емкости, следующая идиома на практике оказывается вполне работоспособной:
container<T>(c).swap(c); // Идиома "горячей посадки" для
// устранения излишней емкости
// контейнера
Для того чтобы полностью опустошить c, удалив все элементы и убрав всю емкость, идиома должна выглядеть следующим образом:
container<T>().swap(c); // Идиома для удаления всего
// содержимого и емкости
Кроме того, обычно для новичков в программировании с использованием STL оказывается сюрпризом то, что алгоритм remove в действительности не удаляет элементы из контейнера. Понятно, что данный алгоритм на это не способен — ведь алгоритм работает только с диапазоном итераторов и не может ничего реально удалить из контейнера без вызова функции-члена контейнера, обычно erase. Удаление сводится к перемещению элементов, которые должны быть "удалены", и возврату итератора, указывающего на элемент, следующий за последним неудаленным. Для реального удаления элементов из контейнера после вызова remove следует вызвать erase — воспользоваться идиомой erase-remove. Например, для реального удаления всех элементов, равных value, из контейнера с, можно написать:
c.erase(remove(c.begin(), c.end(), value), c.end());
Если контейнер имеет собственную версию remove или remove_if, желательно использовать именно ее.
Исключения
Описанная идиома "горячей усадки" не работает с реализациями std::string с копированием при записи. Обычно работает вызов s.reserve(0) или такой трюк, как string(s.begin(), s.end()).swap(s);, в котором использован конструктор на основе двух итераторов. На практике эти методы обычно работают и устраняют излишнюю емкость. (Было бы еще лучше, чтобы реализации std::string не использовали такой устаревший метод оптимизации, как копирование при записи; см. [Sutter02].)
Ссылки
[Josuttis99] §6.2.1 • [Meyers01] §17, §32, §44 • [Sutter00] §7 • [Sutter02] §7, §16
Более 800 000 книг и аудиокниг! 📚
Получи 2 месяца Литрес Подписки в подарок и наслаждайся неограниченным чтением
ПОЛУЧИТЬ ПОДАРОКЧитайте также
Дросселирование семафора для уменьшения состязательности между потоками
Дросселирование семафора для уменьшения состязательности между потоками Слишком большое количество потоков, соревнующихся между собой за право владения единственным ресурсом, например, мьютексом или объектом CS, могут стать причиной снижения производительности как в
10.13.10 Снижение перегрузок за счет уменьшения пересылаемых по сети данных
10.13.10 Снижение перегрузок за счет уменьшения пересылаемых по сети данных Сокращение объема пересылаемых данных несколько сложнее, чем рассмотренные выше механизмы. Оно начинает работать, как и уже упомянутый медленный старт. Но, поскольку устанавливается граница для
Добавление новых элементов в панель элементов управления
Добавление новых элементов в панель элементов управления Чтобы получить возможность использовать элемент управления ActiveX, выполните следующее.1. Установите программное обеспечение элемента управления на жесткий диск.Мне кажется, это имеет смысл.2. Зарегистрируйте
Реализация паттерна««Шаблонный метод» с помощью идиомы невиртуального интерфейса
Реализация паттерна««Шаблонный метод» с помощью идиомы невиртуального интерфейса Начнем с интересной концепции, которая утверждает, что виртуальные функции почти всегда должны быть закрытыми. Сторонники этой школы предполагают, что правильно было бы оставить
1.5.4. Рубизмы и идиомы
1.5.4. Рубизмы и идиомы Материал в этом разделе во многом пересекается с изложенным выше. Но не задумывайтесь особо, почему мы решили разбить его именно таким образом. Просто многие вещи трудно точно классифицировать и организовать единственно правильным образом. Мы
7.1. Перебор элементов контейнера
7.1. Перебор элементов контейнера ПроблемаИмеется диапазон итераторов — скорее всего, из стандартного контейнера — и стандартные алгоритмы не удовлетворяют вашим требованиям, так что вам требуется выполнить итерации самостоятельно.РешениеДля доступа к элементам
7.2. Удаление объектов из контейнера
7.2. Удаление объектов из контейнера ПроблемаТребуется удалить объекты из контейнера.РешениеДля удаления одного или диапазона элементов используйте метод контейнера erase или один из стандартных алгоритмов. Пример 7.2 показывает пару различных способов удаления элементов
11.3. Вычисление суммы и среднего значения элементов контейнера
11.3. Вычисление суммы и среднего значения элементов контейнера ПроблемаТребуется вычислить сумму и среднее значение чисел, содержащихся в контейнере.РешениеДля расчета суммы можно использовать функцию accumulate из заголовочного файла <numeric> и затем разделить ее на
Совет 17. Используйте «фокус с перестановкой» для уменьшения емкости
Совет 17. Используйте «фокус с перестановкой» для уменьшения емкости Предположим, вы пишете программу для нового телешоу «Бешеные деньги». Информация о потенциальных участниках хранится в векторе:class Contestant {...};vector<Contestant> contestants;При объявлении набора участников заявки
Операции увеличения и уменьшения: ++ и --
Операции увеличения и уменьшения: ++ и -- Операция увеличения осуществляет следующее простое действие: она увеличивает значение своего операнда на единицу. Существуют две возможности использования данной операции, первая: когда символы ++ находятся слева от
Операция уменьшения: --
Операция уменьшения: -- Каждой операции увеличения соответствует некоторая операция уменьшения, при этом вместо символов ++ мы используем -- -- count, /* префиксная форма операции уменьшения */count --, /* постфиксная форма операции уменьшения */ Ниже приводится пример,
Хранение элементов в коллекциях и получение элементов из коллекций
Хранение элементов в коллекциях и получение элементов из коллекций Коллекции — это такие объекты, в экземплярах которых могут храниться другие объекты. Одна из самых распространенных разновидностей коллекций — это массив, который инстанцирует NSArray или NSMutableArray. В
12.5.3. Алгоритмы удаления и подстановки
12.5.3. Алгоритмы удаления и подстановки Рассмотрим последовательность из трех символов: {a,b,c}. Для нее существует шесть различных перестановок: abc, acb, bac, bca, cab и cba, лексикографически упорядоченных на основе оператора “меньше”. Таким образом, abc – это первая перестановка,
Подходящие типы элементов
Подходящие типы элементов Массивы могут содержать элементы любого поддерживаемого Firebird типа за исключением BLOB. Массивы массивов не поддерживаются. Все элементы конкретного массива имеют один и тот же тип