跳到主要内容

std::vector reserve() 方法

// prism-push-types:size_type
// Non const version only
constexpr void reserve( size_type new_cap );

增加 vector 的容量(vector 可以容纳的元素总数,无需重新分配)到一个**大于或等于** new_cap 的值。如果 new_cap 大于当前的 capacity(),则会分配新的存储空间,否则函数不执行任何操作。

重要

reserve() 不会改变 vector 的大小。

失效

如果 new_cap 大于 capacity(),所有**迭代器**,包括**末尾迭代器**,以及所有元素的**引用**都将失效。

否则,**没有迭代器或引用**失效。

参数

  • new_cap - vector 的新容量,以元素数量表示

类型要求

  • T (容器的元素类型)必须满足 MoveInsertable 的要求。

返回值

(无)

复杂度

最多与容器的 size() 成线性关系 - **O(sizes())**。

异常

如果抛出异常,此函数不产生任何效果(强异常保证)。

如果 T 的移动构造函数**不是 noexcept** 且 T **不可复制插入**到 *this,则 vector 将使用抛出异常的移动构造函数。如果它抛出异常,则保证失效,效果未指定。

备注

正确使用 reserve() 可以防止不必要的重新分配,但不恰当地使用 reserve()(例如,在每次调用 push_back() 之前都调用它)实际上可能会增加重新分配的次数(导致容量线性增长而不是指数增长),并导致计算复杂性增加和性能下降。

例如,一个通过引用接收任意 vector 并向其中添加元素的函数通常不应该对该 vector 调用 reserve(),因为它不知道该 vector 的使用特性。

当插入一个范围时,通常更推荐使用 insert() 的范围版本,因为它保留了正确的容量增长行为,这与 reserve() 后跟一系列 push_back() 不同。

reserve() 不能用于减少容器的容量;为此提供了 shrink_to_fit()

示例

Main.cpp
#include <cstddef>
#include <iostream>
#include <new>
#include <vector>

// minimal C++11 allocator with debug output
template <class Tp>
struct NAlloc {
typedef Tp value_type;
NAlloc() = default;
template <class T> NAlloc(const NAlloc<T>&) {}

Tp* allocate(std::size_t n)
{
n *= sizeof(Tp);
Tp* p = static_cast<Tp*>(::operator new(n));
std::cout << "allocating " << n << " bytes @ " << p << '\n';
return p;
}

void deallocate(Tp* p, std::size_t n)
{
std::cout << "deallocating " << n*sizeof*p << " bytes @ " << p << "\n\n";
::operator delete(p);
}
};
template <class T, class U>
bool operator==(const NAlloc<T>&, const NAlloc<U>&) { return true; }
template <class T, class U>
bool operator!=(const NAlloc<T>&, const NAlloc<U>&) { return false; }

int main()
{
constexpr int max_elements = 32;

std::cout << "using reserve: \n";
{
std::vector<int, NAlloc<int>> v1;
v1.reserve( max_elements ); // reserves at least max_elements * sizeof(int) bytes

for(int n = 0; n < max_elements; ++n)
v1.push_back(n);
}

std::cout << "not using reserve: \n";
{
std::vector<int, NAlloc<int>> v1;

for(int n = 0; n < max_elements; ++n) {
if(v1.size() == v1.capacity()) {
std::cout << "size() == capacity() == " << v1.size() << '\n';
}
v1.push_back(n);
}
}
}
可能输出
using reserve: 
allocating 128 bytes @ 0xa6f840
deallocating 128 bytes @ 0xa6f840

not using reserve:
size() == capacity() == 0
allocating 4 bytes @ 0xa6f840

size() == capacity() == 1
allocating 8 bytes @ 0xa6f860
deallocating 4 bytes @ 0xa6f840

size() == capacity() == 2
allocating 16 bytes @ 0xa6f840
deallocating 8 bytes @ 0xa6f860

size() == capacity() == 4
allocating 32 bytes @ 0xa6f880
deallocating 16 bytes @ 0xa6f840

size() == capacity() == 8
allocating 64 bytes @ 0xa6f8b0
deallocating 32 bytes @ 0xa6f880

size() == capacity() == 16
allocating 128 bytes @ 0xa6f900
deallocating 64 bytes @ 0xa6f8b0

deallocating 128 bytes @ 0xa6f900
本文档源自 此 CppReference 页面。它可能为了改进或编辑者的偏好而进行了修改。点击“编辑此页面”查看此文档的所有更改。
悬停查看原始许可证。

std::vector reserve() 方法

// prism-push-types:size_type
// Non const version only
constexpr void reserve( size_type new_cap );

增加 vector 的容量(vector 可以容纳的元素总数,无需重新分配)到一个**大于或等于** new_cap 的值。如果 new_cap 大于当前的 capacity(),则会分配新的存储空间,否则函数不执行任何操作。

重要

reserve() 不会改变 vector 的大小。

失效

如果 new_cap 大于 capacity(),所有**迭代器**,包括**末尾迭代器**,以及所有元素的**引用**都将失效。

否则,**没有迭代器或引用**失效。

参数

  • new_cap - vector 的新容量,以元素数量表示

类型要求

  • T (容器的元素类型)必须满足 MoveInsertable 的要求。

返回值

(无)

复杂度

最多与容器的 size() 成线性关系 - **O(sizes())**。

异常

如果抛出异常,此函数不产生任何效果(强异常保证)。

如果 T 的移动构造函数**不是 noexcept** 且 T **不可复制插入**到 *this,则 vector 将使用抛出异常的移动构造函数。如果它抛出异常,则保证失效,效果未指定。

备注

正确使用 reserve() 可以防止不必要的重新分配,但不恰当地使用 reserve()(例如,在每次调用 push_back() 之前都调用它)实际上可能会增加重新分配的次数(导致容量线性增长而不是指数增长),并导致计算复杂性增加和性能下降。

例如,一个通过引用接收任意 vector 并向其中添加元素的函数通常不应该对该 vector 调用 reserve(),因为它不知道该 vector 的使用特性。

当插入一个范围时,通常更推荐使用 insert() 的范围版本,因为它保留了正确的容量增长行为,这与 reserve() 后跟一系列 push_back() 不同。

reserve() 不能用于减少容器的容量;为此提供了 shrink_to_fit()

示例

Main.cpp
#include <cstddef>
#include <iostream>
#include <new>
#include <vector>

// minimal C++11 allocator with debug output
template <class Tp>
struct NAlloc {
typedef Tp value_type;
NAlloc() = default;
template <class T> NAlloc(const NAlloc<T>&) {}

Tp* allocate(std::size_t n)
{
n *= sizeof(Tp);
Tp* p = static_cast<Tp*>(::operator new(n));
std::cout << "allocating " << n << " bytes @ " << p << '\n';
return p;
}

void deallocate(Tp* p, std::size_t n)
{
std::cout << "deallocating " << n*sizeof*p << " bytes @ " << p << "\n\n";
::operator delete(p);
}
};
template <class T, class U>
bool operator==(const NAlloc<T>&, const NAlloc<U>&) { return true; }
template <class T, class U>
bool operator!=(const NAlloc<T>&, const NAlloc<U>&) { return false; }

int main()
{
constexpr int max_elements = 32;

std::cout << "using reserve: \n";
{
std::vector<int, NAlloc<int>> v1;
v1.reserve( max_elements ); // reserves at least max_elements * sizeof(int) bytes

for(int n = 0; n < max_elements; ++n)
v1.push_back(n);
}

std::cout << "not using reserve: \n";
{
std::vector<int, NAlloc<int>> v1;

for(int n = 0; n < max_elements; ++n) {
if(v1.size() == v1.capacity()) {
std::cout << "size() == capacity() == " << v1.size() << '\n';
}
v1.push_back(n);
}
}
}
可能输出
using reserve: 
allocating 128 bytes @ 0xa6f840
deallocating 128 bytes @ 0xa6f840

not using reserve:
size() == capacity() == 0
allocating 4 bytes @ 0xa6f840

size() == capacity() == 1
allocating 8 bytes @ 0xa6f860
deallocating 4 bytes @ 0xa6f840

size() == capacity() == 2
allocating 16 bytes @ 0xa6f840
deallocating 8 bytes @ 0xa6f860

size() == capacity() == 4
allocating 32 bytes @ 0xa6f880
deallocating 16 bytes @ 0xa6f840

size() == capacity() == 8
allocating 64 bytes @ 0xa6f8b0
deallocating 32 bytes @ 0xa6f880

size() == capacity() == 16
allocating 128 bytes @ 0xa6f900
deallocating 64 bytes @ 0xa6f8b0

deallocating 128 bytes @ 0xa6f900
本文档源自 此 CppReference 页面。它可能为了改进或编辑者的偏好而进行了修改。点击“编辑此页面”查看此文档的所有更改。
悬停查看原始许可证。