std::inplace_vector - cppreference.com
来自cppreference.com
template< class T, std::size_t N > struct inplace_vector; |
(C++26 起) | |
std::inplace_vector 是具有连续原位存储的可动态调整大小的数组。在对象自身内部存储 T 类型的元素并且适当对齐。内部存储的容量是在编译时固定的,等于 N。
各元素连续存储,这表示不仅可以通过迭代器或者随机访问的 operator[] 来访问元素,也可以在指向元素的常规指针上使用偏移量。可以将指向 inplace_vector 元素的指针传递给任何接受指向 C 数组元素指针的函数。
std::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。
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_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
|
由实现定义的指向 value_type 的老式随机访问迭代器 (LegacyRandomAccessIterator) 和 random_access_iterator[编辑]
|
const_iterator
|
由实现定义的指向 const value_type 的老式随机访问迭代器 (LegacyRandomAccessIterator) 、常量表达式迭代器 (ConstexprIterator) (C++26 起)和 random_access_iterator[编辑]
|
reverse_iterator
|
std::reverse_iterator<iterator>[编辑]
|
const_reverse_iterator
|
std::reverse_iterator<const_iterator>[编辑]
|
成员函数
构造 inplace_vector (公开成员函数) [编辑] | |
析构 inplace_vector (公开成员函数) [编辑] | |
| 将值赋给容器 (公开成员函数) [编辑] | |
| 将值赋给容器 (公开成员函数) [编辑] | |
| 将范围的值赋给容器 (公开成员函数) [编辑] | |
元素访问 | |
| 带越界检查访问指定的元素 (公开成员函数) [编辑] | |
| 访问指定的元素 (公开成员函数) [编辑] | |
| 访问第一个元素 (公开成员函数) [编辑] | |
| 访问最后一个元素 (公开成员函数) [编辑] | |
| 直接访问底层连续存储 (公开成员函数) [编辑] | |
迭代器 | |
| 返回指向起始的迭代器 (公开成员函数) [编辑] | |
| 返回指向末尾的迭代器 (公开成员函数) [编辑] | |
| 返回指向起始的逆向迭代器 (公开成员函数) [编辑] | |
| 返回指向末尾的逆向迭代器 (公开成员函数) [编辑] | |
大小与容量 | |
| 检查容器是否为空 (公开成员函数) [编辑] | |
| 返回元素数 (公开成员函数) [编辑] | |
[静态] |
返回可容纳的最大元素数 (公开静态成员函数) [编辑] |
[静态] |
返回当前存储空间能够容纳的元素数 (公开静态成员函数) [编辑] |
| 改变存储元素的个数 (公开成员函数) [编辑] | |
[静态] |
预留存储空间 (公开静态成员函数) [编辑] |
[静态] |
通过释放未使用的内存减少内存的使用 (公开静态成员函数) [编辑] |
修改器 | |
| 插入元素 (公开成员函数) [编辑] | |
| 插入元素范围 (公开成员函数) [编辑] | |
| 原位构造元素 (公开成员函数) [编辑] | |
| 在容器末尾原位构造元素 (公开成员函数) [编辑] | |
| 尝试在容器末尾原位构造元素 (公开成员函数) [编辑] | |
| 无条件在容器末尾原位构造元素 (公开成员函数) [编辑] | |
| 将元素添加到容器末尾 (公开成员函数) [编辑] | |
| 尝试将元素添加到容器末尾 (公开成员函数) [编辑] | |
| 无条件将元素添加到容器末尾 (公开成员函数) [编辑] | |
| 移除末元素 (公开成员函数) [编辑] | |
| 添加元素的范围到末尾 (公开成员函数) [编辑] | |
| 清除内容 (公开成员函数) [编辑] | |
| 擦除元素 (公开成员函数) [编辑] | |
| 交换内容 (公开成员函数) [编辑] | |
非成员函数
注解
inplace_vector 的元素数量可动态变化,最多到一个固定的容量,这是由于各元素是存储在对象自身内部,这与 std::array 相似。不过与 C 数组或 std::array 必须在初始化时构造全部元素不同,对象是在插入到 inplace_vector 之内时初始化的。
inplace_vector 在不希望进行动态内存分配的情形中非常有用。
| 功能特性测试宏 | 值 | 标准 | 功能特性 |
|---|---|---|---|
__cpp_lib_inplace_vector |
202406L |
(C++26) | std::inplace_vector: 具有固定容量的原位存储的可动态调整大小的向量
|
202603L |
(C++26) | 为 try_push_back() 和 try_emplace_back() 提供更好的返回类型。移除了 try_append_range()
| |
__cpp_lib_constexpr_inplace_vector |
202502L |
(C++26) | constexpr std::inplace_vector 用于非平凡元素类型
|
示例
#include <algorithm> #include <array> #include <cassert> #include <inplace_vector> #include <optional> 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) != std::nullopt); assert(v1.back() == 3); assert(v1.size() == 4); assert(v1.try_push_back(13) == std::nullopt); // 没有位置 assert(v1.back() == 3); assert(v1.size() == 4); v1.clear(); assert(v1.size() == 0); assert(v1.empty()); }