std::inplace_vector
定义在头文件 <inplace_vector> 中 |
||
template< class T, |
(自 C++26 起) | |
inplace_vector
是一种动态可调整大小的数组,具有连续的原地存储。 类型为 T
的元素存储在对象本身中,并正确对齐。 内部存储的容量在编译时固定,等于 N
。
元素是连续存储的,这意味着元素不仅可以通过迭代器或随机访问 operator[] 访问,还可以使用指向元素的常规指针的偏移量访问。 指向 inplace_vector
元素的指针可以传递给任何期望指向 C 数组元素的指针的函数。
inplace_vector
符合 Container、ReversibleContainer、ContiguousContainer 和 SequenceContainer 的模型,包括大多数 可选的序列容器需求,除了未提供 push_front
、emplace_front
、pop_front
和 prepend_range
成员函数。
对于任何 N
,std::inplace_vector<T, N>::iterator 和 std::inplace_vector<T, N>::const_iterator 满足 ConstexprIterator 需求。
如果 N > 0 并且 std::is_trivial_v<T> 为 false,则 inplace_vector
的成员函数 不可用于常量表达式。
特化 std::inplace_vector<T, 0> 是一个 TrivialType 并且为空。
任何会导致在容量 N
之外插入的 std::inplace_vector<T, N> 的成员函数都会抛出 std::bad_alloc。
对 inplace_vector
的常见操作的复杂度如下
- 通过
operator[]
或at()
随机访问元素 – 常数:𝓞(1). - 在末尾插入或删除元素 – 常数:𝓞(1).
- 在末尾插入或删除元素 – 插入/删除元素的数量的线性关系:𝓞(n).
- 在开头或中间插入或删除元素 – 插入/删除元素的数量的线性关系,加上到向量末尾的距离:𝓞(n).
内容 |
[编辑] 迭代器失效
std::inplace_vector
迭代器失效保证与 std::vector 不同
- 移动
inplace_vector
会使所有迭代器失效; - 交换两个
inplace_vector
会使所有迭代器失效(在交换期间,迭代器将继续指向同一个数组元素,因此其值可能会改变)。
以下成员函数可能会使迭代器失效:operator=
、assign
、assign_range
、clear
、emplace
、erase
、insert
、insert_range
、pop_back
、resize
和 swap
。
以下成员函数可能会使 end
迭代器失效:append_range
、emplace_back
、push_back
、try_append_range
、try_emplace_back
、try_push_back
、unchecked_emplace_back
和 unchecked_push_back
。
[编辑] 模板参数
T | - | 元素类型。必须是 MoveConstructible 和 MoveAssignable。 |
N | - | 容量,即 inplace_vector 中元素的最大数量(可能为 0)。 |
[编辑] 成员类型
成员类型 | 定义 |
value_type
|
T |
size_type
|
std::size_t |
difference_type
|
std::ptrdiff_t |
引用
|
value_type& |
常量引用
|
const value_type& |
指针
|
value_type* |
常量指针
|
const value_type* |
迭代器
|
实现定义的 LegacyRandomAccessIterator 和 random_access_iterator 到 value_type |
常量迭代器
|
实现定义的 LegacyRandomAccessIterator 和 random_access_iterator 到 const value_type |
反向迭代器
|
std::reverse_iterator<iterator> |
常量反向迭代器
|
std::reverse_iterator<const_iterator> |
[编辑] 成员函数
构造 inplace_vector (公共成员函数) | |
析构 inplace_vector (公共成员函数) | |
将值赋值给容器 (公共成员函数) | |
将值赋值给容器 (公共成员函数) | |
将一系列值赋值给容器 (公共成员函数) | |
元素访问 | |
访问指定元素,进行边界检查 (公共成员函数) | |
访问指定元素 (公共成员函数) | |
访问第一个元素 (公共成员函数) | |
访问最后一个元素 (公共成员函数) | |
直接访问底层连续存储 (公共成员函数) | |
迭代器 | |
返回指向开始的迭代器 (公共成员函数) | |
返回指向末尾的迭代器 (公共成员函数) | |
返回指向开始的反向迭代器 (公共成员函数) | |
返回指向末尾的反向迭代器 (公共成员函数) | |
大小和容量 | |
检查容器是否为空 (公共成员函数) | |
返回元素数量 (公共成员函数) | |
[静态] |
返回可能的最大元素数量 (公共静态成员函数) |
[静态] |
返回当前分配的存储中可以容纳的元素数量 (公共静态成员函数) |
更改存储的元素数量 (公共成员函数) | |
[静态] |
预留存储空间 (公共静态成员函数) |
[静态] |
通过释放未使用的内存来减少内存使用量 (公共静态成员函数) |
修改器 | |
插入元素 (公共成员函数) | |
插入一系列元素 (公共成员函数) | |
在原地构造元素 (公共成员函数) | |
在末尾原地构造元素 (公共成员函数) | |
尝试在末尾原地构造元素 (公共成员函数) | |
无条件地在末尾原地构造元素 (公共成员函数) | |
在末尾添加元素 (公共成员函数) | |
尝试在末尾添加元素 (公共成员函数) | |
无条件地在末尾添加元素 (公共成员函数) | |
删除最后一个元素 (公共成员函数) | |
在末尾添加一系列元素 (公共成员函数) | |
尝试在末尾添加一系列元素 (公共成员函数) | |
清除内容 (公共成员函数) | |
删除元素 (公共成员函数) | |
交换内容 (公共成员函数) |
[编辑] 非成员函数
专门化了 std::swap 算法 (函数模板) | |
擦除所有满足特定条件的元素 (函数模板) | |
(C++26) |
按字典顺序比较两个 inplace_vector 的值(函数模板) |
[编辑] 注释
inplace_vector
中的元素数量可以动态地变化,直到达到固定的容量,因为元素类似于 std::array 那样存储在对象本身内。但是,与 C 数组或 std::array 不同,对象是在插入到 inplace_vector
时初始化的,后者必须在实例化时构造所有元素。
inplace_vector
在不需要动态内存分配的环境中很有用。
功能测试 宏 | 值 | Std | 功能 |
---|---|---|---|
__cpp_lib_inplace_vector |
202406L | (C++26) | std::inplace_vector :具有固定容量就地存储的动态可调整大小的向量 |
[编辑] 示例
#include <algorithm> #include <array> #include <cassert> #include <inplace_vector> int main() { std::inplace_vector<int, 4> v1{0, 1, 2}; assert(v1.max_size() == 4); assert(v1.capacity() == 4); assert(v1.size() == 3); assert(std::ranges::equal(v1, std::array{0, 1, 2})); assert(v1[0] == 0); assert(v1.at(0) == 0); assert(v1.front() == 0); assert(*v1.begin() == 0); assert(v1.back() == 2); v1.push_back(3); assert(v1.back() == 3); assert(std::ranges::equal(v1, std::array{0, 1, 2, 3})); v1.resize(3); assert(std::ranges::equal(v1, std::array{0, 1, 2})); assert(v1.try_push_back(3) != nullptr); assert(v1.back() == 3); assert(v1.size() == 4); assert(v1.try_push_back(13) == nullptr); // no place assert(v1.back() == 3); assert(v1.size() == 4); v1.clear(); assert(v1.size() == 0); assert(v1.empty()); }
[编辑] 另请参见
动态连续数组 (类模板) | |
(C++11) |
固定大小的就地连续数组 (类模板) |
双端队列 (类模板) |
[编辑] 外部链接
inplace_vector — P0843R14 (std::inplace_vector ) 的参考实现。 | |
static_vector — Boost.Container 以其自身保证的方式实现了就地向量作为独立类型。 | |
fixed_vector — EASTL 通过额外的模板参数实现了就地向量。 | |
small_vector — Folly 也通过额外的模板参数实现了就地向量。 | |
stack_alloc — Howard Hinnant 的自定义分配器,它在 std::vector 之上模拟 std::inplace_vector 。 |