std::inplace_vector

来自cppreference.com
< cpp‎ | container
 
 
 
 
在标头 <inplace_vector> 定义
template<

    class T,
    std::size_t N

>struct inplace_vector;
(C++26 起)

inplace_vector 是具有连续原位存储的可动态调整大小的数组。在对象自身内部存储 T 类型的元素并且适当对齐。内部存储的容量是在编译时固定的,等于 N

各元素连续存储,这表示不仅可以通过迭代器或者随机访问的 operator[] 来访问元素,也可以在指向元素的常规指针上使用偏移量。可以将指向 inplace_vector 元素的指针传递给任何接受指向 C 数组元素指针的函数。

inplace_vector 实现容器(Container) 可逆容器(ReversibleContainer) 连续容器(ContiguousContainer) 序列容器(SequenceContainer) ,包括大多数可选序列容器操作,但不提供成员函数 push_frontemplace_frontpop_frontprepend_range

对于任意正数 Nstd::inplace_vector<T, N>::iteratorstd::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=assignassign_rangeclearemplaceeraseinsertinsert_rangepop_backresize 以及 swap

这些成员函数仅会潜在地使 end 迭代器失效: append_rangeemplace_backpush_backtry_append_rangetry_emplace_backtry_push_backunchecked_emplace_back 以及 unchecked_push_back

[编辑]模板形参

T - 元素的类型。必须满足可移动构造(MoveConstructible) 可移动赋值(MoveAssignable)
N - 容量,即 inplace_vector 中元素的最大数量(可能为 0)。

[编辑]成员类型

类型 定义
value_typeT[编辑]
size_typestd::size_t[编辑]
difference_typestd::ptrdiff_t[编辑]
referencevalue_type&[编辑]
const_referenceconst value_type&[编辑]
pointervalue_type*[编辑]
const_pointerconst value_type*[编辑]
iterator 由实现定义的指向 value_type老式随机访问迭代器(LegacyRandomAccessIterator) random_access_iterator[编辑]
const_iterator 由实现定义的指向 const value_type老式随机访问迭代器(LegacyRandomAccessIterator) 常量表达式迭代器(ConstexprIterator) (C++26 起)random_access_iterator[编辑]
reverse_iteratorstd::reverse_iterator<iterator>[编辑]
const_reverse_iteratorstd::reverse_iterator<const_iterator>[编辑]

[编辑]成员函数

构造 inplace_vector
(公开成员函数)[编辑]
析构 inplace_vector
(公开成员函数)[编辑]
将值赋给容器
(公开成员函数)[编辑]
将值赋给容器
(公开成员函数)[编辑]
将范围的值赋给容器
(公开成员函数)[编辑]
元素访问
带越界检查访问指定的元素
(公开成员函数)[编辑]
访问指定的元素
(公开成员函数)[编辑]
访问第一个元素
(公开成员函数)[编辑]
访问最后一个元素
(公开成员函数)[编辑]
直接访问底层连续存储
(公开成员函数)[编辑]
迭代器
返回指向起始的迭代器
(公开成员函数)[编辑]
返回指向末尾的迭代器
(公开成员函数)[编辑]
返回指向起始的逆向迭代器
(公开成员函数)[编辑]
返回指向末尾的逆向迭代器
(公开成员函数)[编辑]
大小与容量
检查容器是否为空
(公开成员函数)[编辑]
返回元素数
(公开成员函数)[编辑]
[静态]
返回可容纳的最大元素数
(公开静态成员函数)[编辑]
[静态]
返回当前存储空间能够容纳的元素数
(公开静态成员函数)[编辑]
改变存储元素的个数
(公开成员函数)[编辑]
[静态]
预留存储空间
(公开静态成员函数)[编辑]
通过释放未使用的内存减少内存的使用
(公开静态成员函数)[编辑]
修改器
插入元素
(公开成员函数)[编辑]
插入元素范围
(公开成员函数)[编辑]
原位构造元素
(公开成员函数)[编辑]
在容器末尾原位构造元素
(公开成员函数)[编辑]
尝试在容器末尾原位构造元素
(公开成员函数)[编辑]
无条件在容器末尾原位构造元素
(公开成员函数)[编辑]
将元素添加到容器末尾
(公开成员函数)[编辑]
尝试将元素添加到容器末尾
(公开成员函数)[编辑]
无条件将元素添加到容器末尾
(公开成员函数)[编辑]
移除末元素
(公开成员函数)[编辑]
添加元素的范围到末尾
(公开成员函数)[编辑]
尝试添加元素的范围到末尾
(公开成员函数)[编辑]
清除内容
(公开成员函数)[编辑]
擦除元素
(公开成员函数)[编辑]
交换内容
(公开成员函数)[编辑]


[编辑]非成员函数

特化 std::swap 算法
(函数模板)[编辑]
擦除所有满足特定判别标准的元素
(函数模板)[编辑]
按照字典顺序比较两个 inplace_vector 的值
(函数模板)[编辑]

[编辑]注解

inplace_vector 的元素数量可动态变化,最多到一个固定的容量,这是由于各元素是存储在对象自身内部,这与 std::array 相似。不过与 C 数组或 std::array 必须在初始化时构造全部元素不同,对象是在插入到 inplace_vector 之内时初始化的。

inplace_vector 在不希望进行动态内存分配的情形中非常有用。

功能特性测试标准功能特性
__cpp_lib_inplace_vector202406L(C++26)std::inplace_vector: 具有固定容量的原位存储的可动态调整大小的向量
__cpp_lib_constexpr_inplace_vector202502L(C++26)constexprstd::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_vectorP0843R14 (std::inplace_vector) 的一个参考实现。
2. static_vector — Boost.Container 将 inplace vector 实现为一个具有自己的保证的独立类型。
3. fixed_vector — EASTL 通过一个额外的模板参数实现 inplace vector。
4. small_vector — Folly 也通过一个额外的模板参数实现 inplace vector。
5. stack_alloc — Howard Hinnant 在 std::vector 上模拟 std::inplace_vector 的自定义分配器。
close