如何在构建时为 std::vector 保留内存?

How do I reserve memory for a std::vector at construction time?

通常我会在构建 std::vector 后立即调用 reserve。这通常不会导致 std::vector 的现有堆分配被破坏并替换为新分配吗?有没有办法在构造时保留内存而不是分配堆 space 然后立即销毁它?或者 std::vector 中是否有实施技巧来确保这不是问题?

可用的构造函数似乎只能用于用值填充 std::vector,而不是显式保留 space。

您的问题基于一个错误的前提,即默认构造的 std::vector<T> 将执行 [零长度] 分配。

它确实没有理由这样做。一个新的向量应该有容量(虽然这是理智的要求,而不是标准)。

因此,您的目标已经内在地满足了。

坦率地说,标准库并不那么愚蠢。

如果您在编译时知道元素的数量,您可以使用这些元素对向量进行列表初始化:

 class MyClass 
 {
      int x, y, z;
      std::vector<int> v;

  public:
         MyClass(int X, int Y, int Z) : x(X), y(Y), z(Z), v{x, y, z}
         {}
 };

但这不是很好维护。还有更高级的技术,例如您可以使 std::vector 使用的自定义分配器可以从预分配的内存池中获取内存,例如:我怀疑您是否真的需要它。现代实现可以轻松优化如此简单的问题。

对象 std::vector 及其元素数组不存在于同一个连续的内存块中,否则每次调整数组大小时其地址都会发生变化,从而无法保持可靠的引用它。该对象的主体仅包含控制变量和指向实际数组的指针,它将与其他局部变量一起在堆栈中实例化(假设您将其用作局部变量)。而此时数组将是空的,并且可能由指向 nullptr 的指针表示。因此,无论您 reserve 在构建时还是在构建后立即进行,都不会发生重大优化。

如果您想要立即保留静态大小的 std::vector,您可以只使用常规 C 数组而不是 std::vector。只要确保它适合堆栈即可。

原因可能有点讽刺,我们 运行 没有函数签名。

需求来自使用场景,我们确切地知道要将多少元素保存到 vector 中,但我们真的不喜欢 n-duplicated elements 构造函数:

std::vector( size_type count, const T& value = T())

不幸的是签名被上面的构造函数占用了。任何其他可能的签名都可能导致问题。例如

  1. vector(size_type count, size_type reserve_count) 将与 T(size_type).

  2. 向量的上述 n 重复元素构造函数冲突
  3. vector(size_type count, const T& value = T(), size_type reserve_count) 是一个可能的解决方案,但它太长而且仍然很无聊。我们需要构造一个在调用 auto v = vector<T>(0, T(), reserve_count)

  4. 时从不使用的默认值

其他可行方案:

  1. 提供类似make_pair/make_unique的功能。

  2. 定义一个从Allocator派生的Reserver,所以我们可以像

  3. 一样使用constructor vector(const Allocator& alloc)

auto v = vector<Type>(new Reserver(reserve_count));