std::inplace_vector
定义于头文件 <inplace_vector> |
||
template< class T, |
(C++26 起) | |
inplace_vector
是一个具有连续就地存储的动态可调整大小的数组。类型为 T
的元素存储在对象自身内部并正确对齐。内部存储的容量在编译时固定,等于 N。
元素是连续存储的,这意味着不仅可以通过迭代器或随机访问 operator[] 访问元素,还可以使用相对于元素常规指针的偏移量进行访问。指向 inplace_vector
元素的指针可以传递给任何期望指向 C 数组元素的指针的函数。
inplace_vector
模型 容器、 可逆容器、 连续容器 和 序列容器,包括大多数 可选序列容器要求,除了不提供 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 | - | 元素类型。必须是 可移动构造 且 可移动赋值。 |
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 (公有成员函数) | |
为容器赋值 (公有成员函数) | |
为容器赋值 (公有成员函数) | |
为容器赋值一个范围的值 (公有成员函数) | |
元素访问 | |
访问指定元素(带边界检查) (公有成员函数) | |
访问指定元素 (公有成员函数) | |
访问第一个元素 (公有成员函数) | |
访问最后一个元素 (公有成员函数) | |
直接访问底层连续存储 (公有成员函数) | |
迭代器 | |
返回指向开头的迭代器 (公有成员函数) | |
返回指向结尾的迭代器 (公有成员函数) | |
返回指向开头的逆向迭代器 (公有成员函数) | |
返回指向结尾的逆向迭代器 (公有成员函数) | |
大小和容量 | |
检查容器是否为空 (公有成员函数) | |
返回元素数量 (公有成员函数) | |
[静态] |
返回最大可能元素数量 (公有静态成员函数) |
[静态] |
返回当前已分配存储可以容纳的元素数量 (公有静态成员函数) |
更改存储的元素数量 (公有成员函数) | |
[静态] |
预留存储空间 (公有静态成员函数) |
[静态] |
通过释放未使用的内存来减少内存使用 (公有静态成员函数) |
修改器 | |
插入元素 (公有成员函数) | |
插入一个范围的元素 (公有成员函数) | |
就地构造元素 (公有成员函数) | |
在末尾就地构造元素 (公有成员函数) | |
尝试在末尾就地构造元素 (公有成员函数) | |
无条件地在末尾就地构造元素 (公有成员函数) | |
在末尾添加元素 (公有成员函数) | |
尝试在末尾添加元素 (公有成员函数) | |
无条件地在末尾添加元素 (公有成员函数) | |
移除最后一个元素 (公有成员函数) | |
在末尾添加一个范围的元素 (公有成员函数) | |
尝试在末尾添加一个范围的元素 (公有成员函数) | |
清除内容 (公有成员函数) | |
擦除元素 (公有成员函数) | |
交换内容 (公有成员函数) |
[编辑] 非成员函数
特化 std::swap 算法 (函数模板) | |
擦除所有满足特定条件的元素 (函数模板) | |
(C++26) |
按字典顺序比较两个 inplace_vector 的值(函数模板) |
[编辑] 注解
inplace_vector
中的元素数量可以在固定容量范围内动态变化,因为元素存储在对象自身内部,类似于 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()); }
[编辑] 参见
resizable contiguous array (class template) | |
(C++11) |
fixed-sized inplace contiguous array (class template) |
double-ended queue (class template) |
[编辑] 外部链接
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 。 |