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 > 是 TriviallyCopyable 且为空。 std:: is_trivially_default_constructible_v < std :: inplace_vector < T, 0 >> 同样为 true 。
任何会导致插入超出容量 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 |
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
(公开成员函数) |
|
析构
inplace_vector
(公开成员函数) |
|
|
为容器赋值
(公开成员函数) |
|
|
为容器赋值
(公开成员函数) |
|
|
将值范围赋值给容器
(公开成员函数) |
|
元素访问 |
|
|
访问指定元素(带边界检查)
(公开成员函数) |
|
|
访问指定元素
(公开成员函数) |
|
|
访问首元素
(公开成员函数) |
|
|
访问最后一个元素
(公开成员函数) |
|
|
直接访问底层连续存储
(公开成员函数) |
|
迭代器 |
|
|
返回指向起始位置的迭代器
(公开成员函数) |
|
|
返回指向末尾的迭代器
(公开成员函数) |
|
|
返回指向起始位置的反向迭代器
(公开成员函数) |
|
|
返回指向末尾的反向迭代器
(公开成员函数) |
|
大小与容量 |
|
|
检查容器是否为空
(公开成员函数) |
|
|
返回元素数量
(公开成员函数) |
|
|
[static]
|
返回可能的最大元素数量
(公开静态成员函数) |
|
[static]
|
返回当前分配存储空间可容纳的元素数量
(公开静态成员函数) |
|
修改存储的元素数量
(公开成员函数) |
|
|
[static]
|
预留存储空间
(公开静态成员函数) |
|
[static]
|
通过释放未使用的内存来减少内存使用量
(公共静态成员函数) |
修饰符 |
|
|
插入元素
(公开成员函数) |
|
|
插入元素范围
(公开成员函数) |
|
|
原地构造元素
(公开成员函数) |
|
|
在末尾就地构造元素
(公开成员函数) |
|
|
尝试在末尾就地构造元素
(公开成员函数) |
|
|
无条件在末尾就地构造元素
(公开成员函数) |
|
|
在末尾添加元素
(公开成员函数) |
|
|
尝试在末尾添加元素
(公开成员函数) |
|
|
无条件在末尾添加元素
(公开成员函数) |
|
|
移除末尾元素
(公开成员函数) |
|
|
将元素范围添加至末尾
(公开成员函数) |
|
|
尝试将元素范围添加到末尾
(公开成员函数) |
|
|
清空内容
(公开成员函数) |
|
|
擦除元素
(公开成员函数) |
|
|
交换内容
(公开成员函数) |
|
非成员函数
|
(C++26)
|
特化
std::swap
算法
(函数模板) |
|
擦除满足特定条件的所有元素
(函数模板) |
|
|
(C++26)
|
按字典序比较两个
inplace_vector
的值
(函数模板) |
注释
inplace_vector
中的元素数量可以动态变化,但不会超过固定容量,因为元素与对象本身存储在一起,类似于
std::array
。然而,与 C 数组或
std::array
必须在实例化时构造所有元素不同,对象在插入
inplace_vector
时才进行初始化。
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); // 无可用空间 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
功能。
|