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 要求。
特化 std::inplace_vector<T, 0> 是 可平凡复制的 且为空。std::is_trivially_default_constructible_v<std::inplace_vector<T, 0>> 也为 true。
std::inplace_vector<T, N>
的任何导致超出容量 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 | - | 元素类型。必须是 可移动构造 和 可移动赋值 的。 |
N | - | 容量,即 inplace_vector 中元素的最大数量(可以是 0)。 |
[编辑] 成员类型
类型 | 定义 |
value_type
|
T |
size_type
|
std::size_t |
difference_type
|
std::ptrdiff_t |
reference
|
value_type& |
const_reference
|
const value_type& |
pointer
|
value_type* |
const_pointer
|
const value_type* |
iterator
|
实现定义的 LegacyRandomAccessIterator 和 random_access_iterator 到 value_type |
const_iterator
|
实现定义的 LegacyRandomAccessIterator,ConstexprIterator(C++26 起) 和 random_access_iterator 到 const value_type |
reverse_iterator
|
std::reverse_iterator<iterator> |
const_reverse_iterator
|
std::reverse_iterator<const_iterator> |
[编辑] 成员函数
构造 inplace_vector (public member function) | |
销毁 inplace_vector (public member function) | |
将值赋给容器 (public member function) | |
将值赋给容器 (public member function) | |
将一个范围的值赋给容器 (public member function) | |
元素访问 | |
访问指定的元素,带边界检查 (public member function) | |
访问指定的元素 (public member function) | |
访问第一个元素 (public member function) | |
访问最后一个元素 (public member function) | |
直接访问底层连续存储 (public member function) | |
迭代器 | |
返回指向起始的迭代器 (public member function) | |
返回指向末尾的迭代器 (public member function) | |
返回指向起始的逆向迭代器 (public member function) | |
返回指向末尾的逆向迭代器 (public member function) | |
大小和容量 | |
检查容器是否为空 (public member function) | |
返回元素数量 (public member function) | |
[静态] |
返回元素的最大可能数量 (public static member function) |
[静态] |
返回当前已分配存储空间中可容纳的元素数量 (public static member function) |
更改存储的元素数量 (public member function) | |
[静态] |
预留存储空间 (public static member function) |
[静态] |
通过释放未使用的内存来减少内存使用 (public static member function) |
修改器 | |
插入元素 (public member function) | |
插入元素范围 (public member function) | |
就地构造元素 (public member function) | |
就地构造元素于结尾 (public member function) | |
尝试在末尾就地构造元素 (public member function) | |
无条件地在末尾就地构造元素 (public member function) | |
添加元素到结尾 (public member function) | |
尝试在末尾添加元素 (public member function) | |
无条件地在末尾添加元素 (public member function) | |
移除末元素 (public member function) | |
添加一个元素范围到结尾 (public member function) | |
尝试在末尾添加一系列元素 (public member function) | |
清除内容 (public member function) | |
擦除元素 (public member function) | |
交换内容 (public member function) |
[编辑] 非成员函数
特化 std::swap 算法 (函数模板) | |
擦除所有满足特定标准的元素 (函数模板) | |
(C++26) |
按字典序比较两个 inplace_vector 的值(函数模板) |
[编辑] 注意
inplace_vector
中的元素数量可以动态变化,直到达到固定容量,因为元素存储在对象本身内部,类似于 std::array。但是,与 C 数组或 std::array 不同,inplace_vector
中的对象在插入时才被初始化,而 C 数组或 std::array 必须在实例化时构造所有元素。
inplace_vector
在不需要动态内存分配的环境中很有用。
特性测试宏 | 值 | 标准 | 特性 |
---|---|---|---|
__cpp_lib_inplace_vector |
202406L |
(C++26) | std::inplace_vector :具有固定容量就地存储的动态可变大小向量 |
__cpp_lib_constexpr_inplace_vector |
202502L |
(C++26) | 针对非平凡元素类型的 constexpr 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) |
固定大小的原位连续数组 (类模板) |
双端队列 (类模板) |
[编辑] 外部链接
1. | inplace_vector — P0843R14 (std::inplace_vector ) 的参考实现。 |
2. | static_vector — Boost.Container 将就地向量实现为具有自身保证的独立类型。 |
3. | fixed_vector — EASTL 通过额外的模板参数实现就地向量。 |
4. | small_vector — Folly 也通过额外的模板参数实现就地向量。 |
5. | stack_alloc — Howard Hinnant 的自定义分配器,它在 std::vector 之上模拟 std::inplace_vector 。 |