C++ vector::erase是否会减少vector::容量?

C++ vector::erase是否会减少vector::容量?,c++,vector,language-lawyer,C++,Vector,Language Lawyer,参考文献只说: 从容器中删除指定的元素。1) 删除元素 在位置2)删除范围[第一;最后]中的元素 使迭代点处或之后的迭代器和引用无效 擦除,包括end()迭代器 迭代器pos必须有效且可取消引用 迭代器(有效,但不可取消引用)不能用作 pos的值 如果first==last,则迭代器first不需要是可取消引用的: 擦除空范围是不可操作的 不一定不行。当阅读C++标准时(和CPUPROCESS代理标准非常好),如果没有明确提到某些东西,那么假设不需要这样的东西。 对C++标准库实现可能是次优的。

参考文献只说:

从容器中删除指定的元素。1) 删除元素 在位置2)删除范围[第一;最后]中的元素

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

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

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


不一定不行。当阅读C++标准时(和CPUPROCESS代理标准非常好),如果没有明确提到某些东西,那么假设不需要这样的东西。


对C++标准库实现可能是次优的。

< P>不。这是由于在擦除之前的迭代器、指针和引用保持有效的事实。减少容量需要重新分配。

< P>影响容量的唯一向量操作是无效的< ST >。rong>所有迭代器、指针和引用,因为它们重新分配了存储并移动了元素

分配器
概念中没有任何东西允许它更改分配大小,因此容量也不能以这种方式更改


理论上,一个实现可以专门处理
std::allocator
并根据“仿佛”规则进行重新分配,但我怀疑是否有任何严肃的实现可以做到这一点。

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

#包括
#包括
int main()
{
向量intVec{1,2,3,4,5,6,7,8,9,10};

std::cout和其他约束,如复杂性或迭代器有效性,可能会以某种方式强制实现

在这里:

复杂性:
删除(销毁)的元素数加上最后一个元素删除(移动)后的元素数为线性

因此,减少容量和移动旧对象是不可能的,除非
first
begin
是相同的


减少容量的数量是可能的,但是我看不到任何明智的实现。

看起来它被调整大小:@ IAN.B.Kin,当然,因为元素被移除,大小必须改变,但是容量不必改变。可比的提到:标准没有指定这个。>阅读C++时。标准(cppreference非常好地代表了标准),如果没有明确提到某个东西,那么假设不需要这样的东西。所以我猜答案是它没有必要?简言之,答案确实是“没有必要”。复杂性要求也意味着。在生成反例时,值得详细说明您的工具链。这并不表明标准不需要更改容量,只是允许change@Caleth:我的意图是用一个例子说明擦除不会触发重新分配,从而不会导致容量的变化ample不能作为一般概念的证明。我的意思是你的例子很好,但你不能从它得出任何结论,一般情况下“其他约束…迭代器无效”-被失效的迭代器不是一个约束。按照说它是失效的标准,重点是实现不需要做任何事情来保持它的有效性。实现不需要刻意使它失效,因为使用它是很困难的-这可能是……它可以工作。@UKMonkey:我的意思是“哪个迭代器应该保持有效”,因此,如果
f()
不应该使迭代器无效,那么重新分配就不会发生。它会使某些实现无效,例如字符串的COW。啊-这更有意义:)
#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;
}