命名空间
变体
操作

std::vector

来自 cppreference.com
< cpp‎ | container
 
 
 
 
定义在头文件 <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 是一个使用 多态分配器 的别名模板。

元素是连续存储的,这意味着元素不仅可以通过迭代器访问,还可以使用指向元素的常规指针的偏移量访问。这意味着指向向量元素的指针可以传递给任何期望指向数组元素的指针的函数。

向量的存储由系统自动处理,并在需要时进行扩展。向量通常比静态数组占用更多空间,因为分配了更多内存来处理未来的增长。这样,向量不需要每次插入元素时都重新分配,而只需要在额外内存耗尽时重新分配。可以使用 capacity() 函数查询已分配内存的总量。可以通过调用 shrink_to_fit()[1] 将额外内存返回给系统。

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

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

  • 随机访问 - 常数 𝓞(1).
  • 在末尾插入或删除元素 - 均摊常数 𝓞(1).
  • 插入或删除元素 - 与向量末端的距离成线性关系 𝓞(n).

std::vector(对于除 bool 以外的 T)满足 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 必须满足 CopyAssignableCopyConstructible 的要求。 (直到 C++11)
对元素施加的要求取决于对容器执行的实际操作。通常要求元素类型是完整类型并满足 Erasable 的要求,但许多成员函数会施加更严格的要求。 (自 C++11 起)
(直到 C++17)

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

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

[编辑]

分配器 - 用于获取/释放内存以及在该内存中构造/销毁元素的分配器。该类型必须满足 Allocator 的要求。 行为未定义(直到 C++20)程序格式错误(自 C++20 起) 如果 Allocator::value_typeT 不相同。 [编辑]

[编辑] 特化

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

空间高效的动态位集
(类模板特化) [编辑]

[编辑] 迭代器失效

操作 失效
所有只读操作 从不。
swapstd::swap end()
clearoperator=assign 总是。
reserveshrink_to_fit 如果向量改变了容量,则所有迭代器失效。如果没有改变,则没有迭代器失效。
erase 被擦除的元素和它们之后的所有元素(包括 end())。
push_backemplace_back 如果向量改变了容量,则所有迭代器失效。如果没有改变,则只有 end() 失效。
insertemplace 如果向量改变了容量,则所有迭代器失效。
如果没有改变,则只有在插入点或之后的那些迭代器失效(包括 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

LegacyRandomAccessIteratorLegacyContiguousIteratorvalue_type

(直到 C++20)

LegacyRandomAccessIteratorcontiguous_iterator,以及 ConstexprIteratorvalue_type

(自 C++20 起)
[编辑]
const_iterator

LegacyRandomAccessIteratorLegacyContiguousIteratorconst value_type

(直到 C++20)

LegacyRandomAccessIteratorcontiguous_iterator,以及 ConstexprIteratorconst 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 起)

[编辑] 备注

功能测试 Std 功能
__cpp_lib_containers_ranges 202202L (C++23) 容器的范围构造和插入

[编辑] 示例

#include <iostream>
#include <vector>
 
int main()
{
    // Create a vector containing integers
    std::vector<int> v = {8, 4, 5, 9};
 
    // Add two more integers to vector
    v.push_back(6);
    v.push_back(9);
 
    // Overwrite element at position 2
    v[2] = -1;
 
    // Print out the 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 的底层存储会导致 UB 提供了 data 函数

[编辑] 另请参阅

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