Как удалить элемент (ы) из std :: vector без изменения его размера - PullRequest
9 голосов
/ 31 марта 2011

стирание итератора (позиция итератора);

стирание итератора (сначала итератор, последний итератор);

Стереть элементы Удаляет из вектора Контейнер либо один элемент (позиция) или ряд элементов ([Первый, последний)).

Это эффективно уменьшает вектор размер по количеству элементов удалены, вызывая каждый элемент деструктор до.

и

удалить

Удаляет все элементы, равные заданное значение значения из диапазона, определяется [первым, последним). Удаление сделано путем смещения элементов в диапазон таким образом, что требуется элементы перезаписываются. Элементы между старым и новым концами диапазон остался нетронутым. Итератор для возвращается новый конец диапазона.

Есть ли способ удалить элементы из std :: vector в пределах диапазона итератора (что-то вроде удаления, но ВСЕ элементы из [first, last]) без изменения размера вектора? Мне нужно сохранить его максимальный размер, которого он достиг во время выполнения, чтобы предотвратить перераспределение.

Спасибо!

Ответы [ 5 ]

14 голосов
/ 31 марта 2011

resize никогда не уменьшит capacity вектора - вы можете безопасно использовать erase для этого.

Используйте reserve, чтобы вектор предварительно выделил пространство для определенного количества элементов.Если вы действительно не превысите этот предел, никакие insert или erase или resize не приведут к перераспределению.Если вы превысите его, вектор будет внутренне reserve больше места - но он не будет уменьшать внутреннюю емкость.

2 голосов
/ 31 марта 2011

Я думаю, что вы, возможно, неправильно понимаете разницу между емкостью вектора и его размером.

Емкость - это насколько большой базовый массив на самом деле. Размер - это количество элементов, которые фактически используются в этом массиве.

Когда вы вызываете стирание / удаление, вы удаляете элементы из массива и перемещаете элементы вперед. Однако большой массив не изменяет его емкость. Изменяется только поле размера вектора (вероятно, просто size_t), а также смещаются некоторые элементы.

Простой пример: Вот int-вектор с емкостью 10 и размером 4.

| 1 | 2 | 4 | 8 | Garbage | Garbage | Garbage | Garbage | Garbage | Garbage |

Теперь, скажем, мы хотим удалить элемент с индексом 1.

Операция будет выглядеть примерно так:

  1. Уничтожить элемент с индексом 1 (в данном случае целое число 2)

  2. Переместить все элементы после индекса 1, которые являются допустимыми вперед, однако необходимо много мест, чтобы не было мусора между началом массива и последним допустимым элементом (в этом случае, сдвиньте все вперед на 1).

  3. Уменьшить поле размера на количество удаленных элементов (в данном случае 1).

Окончательный вектор: | 1 | 4 | 8 | Garbage | Garbage | Garbage | Garbage | Garbage | Garbage | Garbage |

Нет необходимости перераспределять массивы, поскольку емкость вектора не изменилась.

Я не совсем уверен в семантике операции сдвига вперед, могут быть некоторые вызовы перегрузок конструктора копирования / оператора присваивания (если они есть) при перемещении элементов вперед.

1 голос
/ 31 марта 2011

Я думаю, что вы хотите использовать функцию reserve, чтобы зарезервировать пространство в векторе для необходимого количества элементов.

Посмотрите здесь: http://www.cplusplus.com/reference/stl/vector/reserve/

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

Запрос на изменение мощности

просит, чтобы емкость выделенное пространство для хранения элементы вектора контейнера будут в по крайней мере, достаточно, чтобы содержать n элементов.

Это сообщает вектор планируемого увеличение в размерах, хотя обратите внимание, что параметр n информирует о минимуме, поэтому результирующая емкость может быть любой емкость равна или больше, чем эта.

Когда n больше текущего емкость, попытка перераспределения во время вызова этой функции. Если успешно, это не дает произойдет автоматическое перераспределение из-за вызова вектора :: insert или vector :: push_back до вектора размер превосходит как минимум п (это сохраняет действительность итераторов на все эти будущие звонки).

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

В любом случае вызов этой функции никогда не влияет на содержащиеся в нем элементы в векторе, ни размер вектора (для этого см. vector :: resize или vector :: erase, которые модифицируют векторный размер и содержание).

0 голосов
/ 31 марта 2011

std :: vector не уменьшает его емкость при уменьшении его размера. На самом деле, чтобы уменьшить емкость вектора, вам нужно использовать идиому swap-with-empty-vector.

0 голосов
/ 31 марта 2011
iterator erase ( iterator first, iterator last );

Это то, что вы хотите сделать.Тот факт, что деструкторы элементов вызываются, не имеет ничего общего с максимальным размером (то есть емкостью) вектора, который обычно не уменьшается.При удалении элемента из вектора размер вектора (= количество содержащихся элементов) уменьшается, но емкость в большинстве случаев не меняется.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...