std::vector<T,Allocator>::reserve
void reserve( size_type new_cap ); |
(constexpr since C++20) | |
增加 vector 的容量(vector 可以容纳而无需重新分配的元素总数)到一个大于或等于 new_cap 的值。如果 new_cap 大于当前的 capacity(),则会分配新的存储空间,否则该函数不执行任何操作。
reserve()
不会更改 vector 的大小。
如果 new_cap 大于 capacity(),则所有迭代器(包括 end()
迭代器)以及对元素的所有引用都将失效。否则,迭代器或引用均不会失效。
在调用 reserve()
之后,除非插入操作会导致 vector 的大小大于 capacity() 的值,否则插入操作将不会触发重新分配。
内容 |
[编辑] 参数
new_cap | - | vector 的新容量,以元素数量为单位 |
类型要求 | ||
-T 必须满足 MoveInsertable 到 *this 的要求。 (C++11 起) |
[编辑] 返回值
(无)
[编辑] 异常
- std::length_error 如果 new_cap > max_size()。
Allocator::allocate()
抛出的任何异常(通常是 std::bad_alloc)。
如果抛出异常,则此函数无效(强异常安全保证)。
如果 |
(C++11 起) |
[编辑] 复杂度
最多与容器的 size() 成线性关系。
[编辑] 注释
正确使用 reserve()
可以防止不必要的重新分配,但不恰当地使用 reserve()
(例如,在每次 push_back() 调用之前调用它)实际上可能会增加重新分配的次数(通过导致容量线性而不是指数增长),并导致计算复杂性增加和性能下降。例如,接收对任意 vector 的引用的函数,并向其追加元素,通常不应在 vector 上调用 reserve()
,因为它不知道 vector 的使用特性。
当插入一个范围时,通常首选 insert() 的范围版本,因为它保留了正确的容量增长行为,这与 reserve()
后跟一系列 push_back() 不同。
reserve()
不能用于减少容器的容量;为此提供了 shrink_to_fit()。
[编辑] 示例
#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
[编辑] 缺陷报告
以下行为变更缺陷报告已追溯应用于先前发布的 C++ 标准。
DR | 应用于 | 已发布行为 | 正确行为 |
---|---|---|---|
LWG 329 | C++98 | 如果插入操作使 vector 的大小大于 最近一次调用 reserve() 中指定的大小,则可能会触发重新分配最近一次调用 reserve() 中指定的大小,则可能会触发重新分配 |
仅当 vector 的大小 变得大于 capacity() 时才触发 变得大于 capacity() 时才触发 |
LWG 2033 | C++11 | T 不需要是 MoveInsertable |
需要 |
[编辑] 参见
返回当前已分配存储空间中可以容纳的元素数量 (公共成员函数) | |
返回最大可能的元素数量 (公共成员函数) | |
更改存储的元素数量 (公共成员函数) | |
(DR*) |
通过释放未使用的内存来减少内存使用量 (公共成员函数) |