首页 文章

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

提问于
浏览
9

迭代器擦除(迭代器位置);迭代器擦除(迭代器优先,迭代器最后);擦除元素从向量容器中移除单个元素(位置)或一系列元素([first,last)) . 这有效地减少了矢量大小,删除了元素的数量,之前调用每个元素的析构函数 .

和:

remove从[first,last]定义的范围中删除所有等于给定值的元素 . 通过移动范围中的元素以便覆盖所需元素来完成移除 . 范围的旧端和新端之间的元素保持不变 . 返回到范围的新结尾的迭代器 .

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

谢谢!

5 回答

  • 0

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

    使用 reserve 为一定数量的项目创建矢量预分配空间 . 除非您实际超过此限制,否则 inserteraseresize 将导致重新分配 . 如果超过它,矢量将在内部 reserve 更多空间 - 但它不会降低内部容量 .

  • 1

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

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

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

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

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

    现在,假设我们要删除索引1处的项目 .

    该操作类似于以下内容:

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

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

    • 通过删除多少项(在本例中为1)减小大小字段 .

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

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

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

  • 2

    我想你想使用 reserve 函数在向量中保留所需项目数的空间 .

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

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

    请求更改容量请求向量容器的元素的已分配存储空间的容量至少足以容纳n个元素 . 这通知向量计划的大小增加,但是注意参数n通知最小值,因此得到的容量可以是等于或大于此的任何容量 . 当n大于当前容量时,在调用此函数期间尝试重新分配 . 如果成功,它授予不会发生进一步的自动重新分配,因为调用vector :: insert或vector :: push_back,直到向量大小超过至少n(这将保留所有这些未来调用的迭代器的有效性) . 重新分配使所有先前获得的迭代器,引用和指向向量元素的指针无效 . 在任何情况下,对此函数的调用都不会影响向量中包含的元素,也不会影响向量大小(为此,请参阅vector :: resize或vector :: erase,它们修改了向量大小和内容) .

  • 14
    iterator erase ( iterator first, iterator last );
    

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

  • 0

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

相关问题