如何在不调整大小的情况下从std :: vector中删除元素

时间:2011-03-31 07:45:39

标签: c++ stl

  

迭代器擦除(迭代器位置);

     

迭代器擦除(迭代器优先,   迭代器最后);

     

擦除元素从向量中移除   容器要么是单个元素   (位置)或一系列元素   ([第一,最后))。

     

这有效地减少了向量   大小由元素数量决定   删除,调用每个元素   析构函数之前。

  

除去

     

删除所有等于的元素   给定值范围内的值,   由[first,last]定义。删除是   通过移动元素来完成   范围以所需的方式   元素被覆盖。要素   在新旧两端之间   范围保持不变。迭代到   返回范围的新结尾。

有没有办法在迭代器范围内删除std :: vector中的元素(比如remove,但是[first,last]中的所有元素)而不调整向量的大小?我需要保持它在运行时达到的最大大小以防止重新分配。

谢谢!

5 个答案:

答案 0 :(得分:14)

resize永远不会减少向量的capacity - 您可以安全地使用erase

使用reserve为一定数量的项目制作矢量预分配空间。除非您确实超出此限制,否则inserteraseresize将导致重新分配。如果超过它,向量将在内部reserve更多空间 - 但它不会减少内部容量。

答案 1 :(得分:2)

我想也许你误解了矢量的容量和它的大小之间的差异。

容量是底层阵列的实际大小。大小是该数组中实际使用的元素数。

当您调用erase / remove时,您将从数组中删除元素并向前移动项目。但是,大阵列不会修改它的容量。只更改了矢量的大小字段(可能只是一个size_t),以及一些元素被移动。

一个简单的例子: 这是一个容量为10,大小为4的int向量。

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

现在,我们要删除索引1处的项目。

该操作类似于以下内容:

  1. 在索引1处销毁该项目(在本例中为整数2)

  2. 移动索引1之后的所有元素,这些元素是有效的,但是需要很多位置以确保数组的开头和最后一个有效项之间没有垃圾(在这种情况下,将所有内容向前移1)。 p>

  3. 根据删除的项目数量减少大小字段(在本例中为1)。

  4. 最终的载体: | 1 | 4 | 8 | Garbage | Garbage | Garbage | Garbage | Garbage | Garbage | Garbage |

    没有必要重新分配任何数组,因为向量的容量没有改变。

    我不完全确定转发操作的语义,在向前移动项目时可能会有一些调用复制构造函数/赋值运算符重载(如果有的话)。

答案 2 :(得分:1)

我认为您希望使用reserve函数在向量中为所需数量的项目保留空间。

看看这里:http://www.cplusplus.com/reference/stl/vector/reserve/

在从向量中移除项目之前,您可以使用当前大小调用reserve来保持容量相同。

  

请求更改容量

     

请求能力   分配的存储空间   矢量容器的元素在   至少足以容纳n个元素。

     

这会通知计划的向量   增加规模,虽然注意到   参数n通知最小值,   因此产生的容量可能是任何   容量等于或大于此。

     

当n大于当前值时   容量,尝试重新分配   在调用此函数期间。如果   成功了,它没有进一步授予   自动重新分配将发生   因为调用了vector :: insert或   vector :: push_back直到向量   尺寸超过至少n(这个   保留迭代器的有效性   所有这些未来的电话)。

     

重新分配使所有人无效   以前获得的迭代器,   引用和指向元素的指针   矢量。

     

无论如何,都要调用此函数   从不影响所包含的元素   在向量中,也不是向量大小   (为此目的,请参阅vector :: resize   或vector :: erase,修改   矢量大小和内容)。

答案 3 :(得分:0)

iterator erase ( iterator first, iterator last );

这就是你想要做的。调用元素的析构函数与矢量的最大大小(即容量)无关,这通常不会减少。从向量中删除元素时,向量的大小(=包含的元素的数量)会减少,但在大多数情况下容量不会改变。

答案 4 :(得分:0)

std :: vector在减小它的大小时并没有降低它的容量。事实上,要缩小向量的容量,您需要使用swap-with-empty-vector惯用法。