【问题标题】:Does vector::erase reduce vector::capacity?vector::erase 是否会减少 vector::capacity?
【发布时间】:2018-05-30 08:12:18
【问题描述】:

Cppreference 只说:

从容器中移除指定的元素。 1) 移除元素 在 pos. 2) 删除范围内的元素 [first;最后)。

在该点处或之后使迭代器和引用无效 擦除,包括 end() 迭代器。

迭代器 pos 必须有效且可取消引用。因此 end() 迭代器(有效,但不可取消引用)不能用作 pos 的值。

如果 first==last,则迭代器 first 不需要是可解引用的: 擦除空范围是无操作的。

【问题讨论】:

标签: c++ vector language-lawyer


【解决方案1】:

不一定没有。在阅读 C++ 标准(并且 cppreference 非常好地代理标准)时,如果没有明确提及某些内容,则假设不需要这样的内容。

对于 C++ 标准库实现来说,这样做可能不是最理想的。

【讨论】:

  • > 在阅读 C++ 标准(并且 cppreference 非常好地代理标准)时,如果没有明确提及某些内容,则假设不需要这样的内容。所以我想答案是没有必要?
  • 简而言之,答案确实是“不一定”。
【解决方案2】:

没有。擦除点之前的迭代器、指针和引用仍然有效这一事实暗示了这一点。减少容量需要重新分配。

【讨论】:

  • 复杂性要求也暗示了。
【解决方案3】:

由于复杂性或迭代器有效性等其他约束,这可能会以某种方式强制实现。

这里:

复杂性:
与删除(破坏)的元素数量加上最后一个删除(移动)元素之后的元素数量成线性关系。

因此,减少容量和移动旧对象是调整大小的缓冲区是不可能的。除非firstbegin 相同。

只减少容量数量是可能的,但我没有看到任何明智的实现这样做。

【讨论】:

  • "其他约束...迭代器无效" - 被无效的迭代器不是约束。按照标准说它是无效的,重点是实现不需要做任何事情来保持它的有效性。该实现不需要竭尽全力使其无效,因为它是 UB 使用它 - 这可能是......它可以工作。
  • @UKMonkey:我的意思是“哪个迭代器应该保持有效”,所以如果f() 不应该使迭代器失效,那么重新分配就不会发生。例如,它会使某些实现无效,例如字符串的 COW。
  • 啊——这更有意义:)
【解决方案4】:

一个简单的例子可以消除你的疑问:(使用 VS2017 编译)

#include <iostream>
#include <vector>

int main()
{
    std::vector<int> intVec{ 1,2,3,4,5,6,7,8,9,10 };
    std::cout << "Capacity and size before erase : " << intVec.capacity() << ", "<< intVec.size() << std::endl;
    intVec.erase(intVec.begin() + 3);
    std::cout << "Capacity and size after erase : " << intVec.capacity() << ", " << intVec.size() << std::endl;
    return 0;
}

输出:

擦除前的容量和大小:10、10

擦除后的容量和大小:10、9

请注意,虽然capacity() 在擦除后不会减少,但size() 肯定会。

【讨论】:

  • 在生成反例时,值得详细说明您的工具链。
  • 这并没有表明标准要求容量没有变化,只是它允许没有变化
  • @Caleth :我的目的是通过一个示例来说明擦除不会触发重新分配,因此不会导致容量发生变化。
  • 一个例子不能作为一般概念的证明
  • ..我的意思是你的例子很好,但你不能从一般情况下得出任何结论
【解决方案5】:

唯一影响容量的向量操作是那些使所有迭代器、指针和引用无效的操作,因为它们已经重新分配了存储空间并移动了元素。

Allocator 概念中没有任何内容允许它更改适当的分配大小,因此容量也不能以这种方式更改。

理论上,一个实现可以专注于std::allocator 并根据“As-if”规则重新分配,但我怀疑是否有任何严肃的实现会做这样的事情。

【讨论】:

    猜你喜欢
    • 2012-07-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-10
    • 2015-03-24
    • 2016-04-26
    相关资源
    最近更新 更多