Namespaces
Variants

std:: vector

From cppreference.net
定义于头文件 <vector>
template <

class T,
class Allocator = std:: allocator < T >

> class vector ;
(1)
namespace pmr {

template < class T >
using vector = std :: vector < T, std:: pmr :: polymorphic_allocator < T >> ;

}
(2) (C++17 起)
1) std::vector 是一种序列容器,用于封装动态大小的数组。
2) std::pmr::vector 是使用 polymorphic allocator 的别名模板。

除了 std::vector<bool> 部分特化之外,元素都是连续存储的,这意味着不仅可以通过迭代器访问元素,还可以使用指向元素的常规指针的偏移量来访问。这意味着可以将指向vector元素的指针传递给任何期望指向数组元素指针的函数。

vector的存储空间由自动管理,会根据需要自动扩展。vector通常比静态数组占用更多空间,因为会分配更多内存以应对未来增长。这样vector就不需要在每次插入元素时重新分配内存,仅在额外内存耗尽时才需要重新分配。已分配内存的总量可以通过 capacity() 函数查询。额外内存可以通过调用 shrink_to_fit() [1] 返还给系统。

在性能方面,重新分配通常是代价高昂的操作。如果预先知道元素数量,可以使用 reserve() 函数来避免重新分配。

向量常见操作的时间复杂度(效率)如下:

  • 随机访问 - 常数时间复杂度 𝓞(1)
  • 末尾元素的插入或移除 - 均摊常数时间复杂度 𝓞(1)
  • 元素的插入或移除 - 与到向量末尾的距离成线性关系 𝓞(n)

std::vector (对于 T 类型不为 bool 的情况)满足 Container AllocatorAwareContainer (自 C++11 起) SequenceContainer ContiguousContainer (自 C++17 起) 以及 ReversibleContainer 的要求。

std::vector 的所有成员函数均为 constexpr :可以在常量表达式的求值过程中创建和使用 std::vector 对象。

然而, std::vector 对象通常不能是 constexpr 的,因为任何动态分配的存储必须在同一常量表达式求值期间释放。

(C++20 起)
  1. 在 libstdc++ 中, shrink_to_fit() 在 C++98 模式下 不可用

目录

模板参数

T - 元素的类型。
T 必须满足 CopyAssignable CopyConstructible 的要求。 (C++11 前)
对元素的要求取决于容器实际执行的操作。通常要求元素类型为完整类型并满足 Erasable 的要求,但许多成员函数会施加更严格的要求。 (C++11 起)
(C++17 前)

对元素的要求取决于容器实际执行的操作。通常要求元素类型满足 Erasable 的要求,但许多成员函数会施加更严格的要求。若分配器满足 分配器完整性要求 ,则可以使用不完整的元素类型实例化此容器(但非其成员)。

功能测试 标准 功能
__cpp_lib_incomplete_container_elements 201505L (C++17) 最小不完整类型支持
(C++17 起)

分配器 - 用于获取/释放内存及构造/销毁该内存中元素的分配器。该类型必须满足 Allocator 的要求。 Allocator::value_type T 不同, 则行为未定义 (C++20 前) 则程序非良构 (C++20 起)

特化

标准库为类型 std::vector 提供了针对 bool 的特化版本,该版本可能针对空间效率进行了优化。

空间优化的动态位集合
(类模板特化)

迭代器失效

操作 失效情况
所有只读操作 永不失效
swap , std::swap end()
clear , operator= , assign 始终失效
reserve , shrink_to_fit 若向量容量改变则全部失效,否则无失效
erase 被擦除元素及其后所有元素(包括 end()
push_back , emplace_back 若向量容量改变则全部失效,否则仅 end() 失效
insert , emplace 若向量容量改变则全部失效
否则仅插入点及之后元素失效(包括 end()
resize 若向量容量改变则全部失效,否则仅 end() 及被擦除元素失效
pop_back 被擦除元素及 end() 失效

成员类型

成员类型 定义
value_type T
allocator_type Allocator
size_type 无符号整数类型(通常为 std::size_t
difference_type 有符号整数类型(通常为 std::ptrdiff_t
reference value_type &
const_reference const value_type &
pointer

Allocator::pointer

(C++11 前)

std:: allocator_traits < Allocator > :: pointer

(C++11 起)
const_pointer

Allocator::const_pointer

(C++11 前)

std:: allocator_traits < Allocator > :: const_pointer

(C++11 起)
iterator

遗留随机访问迭代器 遗留连续迭代器 指向 value_type

(C++20 前)

遗留随机访问迭代器 contiguous_iterator 常量表达式迭代器 指向 value_type

(C++20 起)
const_iterator

遗留随机访问迭代器 遗留连续迭代器 指向 const value_type

(C++20 前)

遗留随机访问迭代器 contiguous_iterator 常量表达式迭代器 指向 const value_type

(C++20 起)
reverse_iterator std:: reverse_iterator < iterator >
const_reverse_iterator std:: reverse_iterator < const_iterator >

成员函数

构造 vector
(公开成员函数)
析构 vector
(公开成员函数)
为容器赋值
(公开成员函数)
为容器赋值
(公开成员函数)
将值范围赋值给容器
(公开成员函数)
返回关联的分配器
(公开成员函数)
元素访问
访问指定元素(带边界检查)
(公开成员函数)
访问指定元素
(公开成员函数)
访问首元素
(公开成员函数)
访问最后一个元素
(公开成员函数)
直接访问底层连续存储
(公开成员函数)
迭代器
返回指向起始位置的迭代器
(公开成员函数)
(C++11)
返回指向末尾的迭代器
(公开成员函数)
返回指向起始位置的反向迭代器
(公开成员函数)
(C++11)
返回指向末尾的反向迭代器
(公开成员函数)
容量
检查容器是否为空
(公开成员函数)
返回元素数量
(公开成员函数)
返回可能的最大元素数量
(公开成员函数)
预留存储空间
(公开成员函数)
返回当前已分配存储空间可容纳的元素数量
(公开成员函数)
通过释放未使用的内存来减少内存使用量
(公共成员函数)
修饰符
清空内容
(公开成员函数)
插入元素
(公开成员函数)
插入元素范围
(公开成员函数)
(C++11)
原地构造元素
(公开成员函数)
擦除元素
(公开成员函数)
在末尾添加元素
(公开成员函数)
在容器末尾就地构造元素
(公开成员函数)
向末尾添加元素范围
(公开成员函数)
移除末尾元素
(公开成员函数)
改变存储的元素数量
(公开成员函数)
交换内容
(公开成员函数)

非成员函数

(C++20 中移除) (C++20 中移除) (C++20 中移除) (C++20 中移除) (C++20 中移除) (C++20)
按字典序比较两个 vector 的值
(函数模板)
特化 std::swap 算法
(函数模板)
擦除满足特定条件的所有元素
(函数模板)

推导指引

(C++17 起)

注释

功能测试 标准 功能
__cpp_lib_containers_ranges 202202L (C++23) 容器的范围构造与插入
__cpp_lib_ranges_reserve_hint 202502L (C++26) ranges::approximately_sized_range ranges::reserve_hint 及对 std::vector 的修改

示例

#include <iostream>
#include <vector>
int main()
{
    // 创建包含整数的vector
    std::vector<int> v = {8, 4, 5, 9};
    // 向vector添加两个整数
    v.push_back(6);
    v.push_back(9);
    // 覆盖位置2处的元素
    v[2] = -1;
    // 输出vector内容
    for (int n : v)
        std::cout << n << ' ';
    std::cout << '\n';
}

输出:

8 4 -1 9 6 9

缺陷报告

以下行为变更缺陷报告被追溯应用于先前发布的 C++ 标准。

DR 适用版本 发布时的行为 正确行为
LWG 69 C++98 未要求 vector 元素的存储连续性 要求连续存储
LWG 230 C++98 T 未要求为 CopyConstructible
(可能无法构造 T 类型的元素)
T 同时要求
CopyConstructible
LWG 464 C++98 访问空 vector 的底层存储会导致未定义行为 提供 data 成员函数

另请参阅

可调整大小、固定容量、就地连续数组
(类模板)
(C++11)
固定大小就地连续数组
(类模板)
双端队列
(类模板)