定义于头文件 <vector>
template< class T, |
(1) | |
namespace pmr { template <class T> |
(2) | (C++17 起) |
1) std::vector
是封装动态数组的顺序容器。
2) std::pmr::vector
是使用多态分配器的模板别名。
元素相继存储,这意味着不仅可通过迭代器,还能用指向元素的常规指针访问元素。这意味着指向 vector 元素的指针能传递给任何期待指向数组元素的指针的函数。 |
(C++03 起) |
vector 的存储是自动管理的,按需扩张收缩。 vector 通常占用多于静态数组的空间,因为要分配更多内存以管理将来的增长。 vector 所用的方式不在每次插入元素时,而只在额外内存耗尽时重分配。分配的内存总量可用 capacity() 函数查询。额外内存可通过对 shrink_to_fit() 的调用返回给系统。 (C++11 起)
重分配通常是性能上有开销的操作。若元素数量已知,则 reserve() 函数可用于消除重分配。
vector 上的常见操作复杂度(效率)如下:
- 随机访问——常数 O(1)
- 在末尾插入或移除元素——均摊常数 O(1)
- 插入或移除元素——与到 vector 结尾的距离成线性 O(n)
std::vector
(对于 bool
以外的 T
)满足容器 (Container) 、具分配器容器 (AllocatorAwareContainer) 、序列容器 (SequenceContainer) 、连续容器 (ContiguousContainer) (C++17 起)及可逆容器 (ReversibleContainer) 的要求。
容量
预留存储空间
std::vector<T,Allocator>::reserve
void reserve( size_type new_cap ); |
增加 vector 的容量到大于或等于 new_cap
的值。若 new_cap
大于当前的 capacity() ,则分配新存储,否则该方法不做任何事。
reserve()
不更改 vector 的 size 。
若 new_cap
大于 capacity() ,则所有迭代器,包含尾后迭代器和所有到元素的引用都被非法化。否则,没有迭代器或引用被非法化。
参数
new_cap | - | vector 的新容量 |
类型要求 | ||
- T 必须满足可移动插入 (MoveInsertable) 的要求。 |
返回值
(无)
异常
- 若 new_cap > max_size() 则为 std::length_error 。
- 任何
Allocator::allocate()
所抛的异常(典型为 std::bad_alloc )
若抛出异常,则此函数无效果(强异常保证)。
若 |
(C++11 起) |
复杂度
至多与容器的 size() 成线性。
注意
不能用 reserve()
减少容器容量。为该目的提供的是 shrink_to_fit() 。
正确使用 reserve()
能避免不必要的分配,但不适当地使用 reserve()
(例如在每次 push_back() 调用前调用它)可能会实际增加重分配的数量(通过导致容量线性而非指数增长)并导致计算复杂度增加,性能下降。
返回当前存储空间能够容纳的元素数
std::vector<T,Allocator>::capacity
size_type capacity() const; |
(C++11 前) | |
size_type capacity() const noexcept; |
(C++11 起) |
返回容器当前已为之分配空间的元素数。
参数
(无)
返回值
当前分配存储的容量。
复杂度
常数。
通过释放未使用的内存减少内存的使用
std::vector<T,Allocator>::shrink_to_fit
void shrink_to_fit(); |
(C++11 起) |
请求移除未使用的容量。
它是减少 capacity() 到 size()非强制性请求。请求是否达成依赖于实现。
若发生重分配,则所有迭代器,包含尾后迭代器,和所有到元素的引用都被非法化。若不发生重分配,则没有迭代器或引用被非法化。
参数
(无)
类型要求 | ||
- T 必须满足可移动插入 (MoveInsertable) 的要求。 |
返回值
(无)
复杂度
至多与容器大小成线性。
注意
若 T 移动构造函数以外的操作抛出异常,则无效果。
修改器
改变容器中可存储元素的个数
std::vector<T,Allocator>::resize
void resize( size_type count, T value = T() ); |
(C++11 前) | |
void resize( size_type count ); |
(1) | (C++11 起) |
void resize( size_type count, const value_type& value ); |
(2) | (C++11 起) |
重设容器大小以容纳 count
个元素。
若当前大小大于 count
,则减小容器为其首 count
个元素。
若当前大小小于 |
(C++11 前) |
若当前大小小于 1) 则后附额外的默认插入的元素 2) 则后附额外的 |
(C++11 起) |
参数
count | - | 容器的大小 |
value | - | 用以初始化新元素的值 |
类型要求 | ||
- 为使用重载 (1) , T 必须满足可移动插入 (MoveInsertable) 和 可默认插入 (DefaultInsertable) 的要求。 |
||
- 为使用重载 (2) , T 必须满足可复制插入 (CopyInsertable) 的要求。 |
返回值
(无)
复杂度
与当前大小和 count
间的差成线性。若容量小于 count
则可能有重分配所致的额外复杂度。
异常
若抛出异常,则此函数无效果(强异常保证)。
重载 (1) 中,若 |
(C++11 起) |
注意
若不想要重载 (1) 中的值初始化,例如元素是非类类型且不需要清零,则可以提供定制的 Allocator::construct 避免。
在重设大小到较小值时, vector
的容量决不减少,因为这会非法化所有的,而非只非法化等价的 pop_back()
调用序列所非法化的迭代器。
调用示例
#include <iostream>
#include <string>
#include <iterator>
#include <algorithm>
#include <functional>
#include <time.h>
#include <vector>
using namespace std;
struct Cell
{
int x;
int y;
Cell() = default;
Cell(int a, int b): x(a), y(b) {}
Cell &operator +=(const Cell &cell)
{
x += cell.x;
y += cell.y;
return *this;
}
Cell &operator +(const Cell &cell)
{
x += cell.x;
y += cell.y;
return *this;
}
Cell &operator *(const Cell &cell)
{
x *= cell.x;
y *= cell.y;
return *this;
}
Cell &operator ++()
{
x += 1;
y += 1;
return *this;
}
bool operator <(const Cell &cell) const
{
if (x == cell.x)
{
return y < cell.y;
}
else
{
return x < cell.x;
}
}
bool operator >(const Cell &cell) const
{
if (x == cell.x)
{
return y > cell.y;
}
else
{
return x > cell.x;
}
}
bool operator ==(const Cell &cell) const
{
return x == cell.x && y == cell.y;
}
};
std::ostream &operator<<(std::ostream &os, const Cell &cell)
{
os << "{" << cell.x << "," << cell.y << "}";
return os;
}
int main()
{
std::cout << std::boolalpha;
std::mt19937 g{std::random_device{}()};
srand((unsigned)time(NULL));
auto generate = []()
{
int n = std::rand() % 10 + 110;
Cell cell{n, n};
return cell;
};
//3) 构造拥有 count 个有值 value 的元素的容器。
std::vector<Cell> vector1(2, generate());
//替换容器的内容。1) 以 count 份 value 的副本替换内容。
std::cout << "vector1: ";
std::copy(vector1.begin(), vector1.end(), std::ostream_iterator<Cell>(std::cout, " "));
std::cout << std::endl;
std::cout << std::endl;
//打印数组真实地址
std::cout << "vector1.data(): " << vector1.data() << std::endl;
//增加 vector 的容量到大于或等于 new_cap 的值。
//若 new_cap 大于当前的 capacity() ,则分配新存储,否则该方法不做任何事。
vector1.reserve(1);
//打印数组真实地址
std::cout << "vector1.data(): " << vector1.data() << std::endl;
//返回容器当前已为之分配空间的元素数。
std::cout << "vector1.capacity(): " << vector1.capacity() << std::endl;
vector1.reserve(3);
//打印数组真实地址
std::cout << "vector1.data(): " << vector1.data() << std::endl;
std::cout << "vector1.capacity(): " << vector1.capacity() << std::endl;
std::cout << std::endl;
//请求移除未使用的容量。它是减少 capacity() 到 size()非强制性请求。
vector1.shrink_to_fit();
std::cout << "vector1.data(): " << vector1.data() << std::endl;
std::cout << "vector1.capacity(): " << vector1.capacity() << std::endl;
std::cout << std::endl;
//3) 构造拥有 count 个有值 value 的元素的容器。
std::vector<Cell> vector2(5, {101, 101});
//替换容器的内容。1) 以 count 份 value 的副本替换内容。
std::cout << "vector2: ";
std::copy(vector2.begin(), vector2.end(), std::ostream_iterator<Cell>(std::cout, " "));
std::cout << std::endl;
//重设容器大小以容纳 count 个元素。
//若当前大小大于 count ,则减小容器为其首 count 个元素。
vector2.resize(3, {102, 102});
std::cout << "vector2: ";
std::copy(vector2.begin(), vector2.end(), std::ostream_iterator<Cell>(std::cout, " "));
std::cout << std::endl;
//若当前大小小于 count ,则后附额外元素,并以 value 的副本初始化
vector2.resize(5, {103, 103});
std::cout << "vector2: ";
std::copy(vector2.begin(), vector2.end(), std::ostream_iterator<Cell>(std::cout, " "));
std::cout << std::endl;
//若当前大小小于 count ,1) 则后附额外的默认插入的元素
vector2.resize(6);
std::cout << "vector2: ";
std::copy(vector2.begin(), vector2.end(), std::ostream_iterator<Cell>(std::cout, " "));
std::cout << std::endl;
return 0;
}