Namespaces
Variants

std::inplace_vector

来自 zh.cppreference.net
 
 
 
 
定义于头文件 <inplace_vector>
template<
    class T,
    std::size_t N
> struct inplace_vector;
(自 C++26 起)

std::inplace_vector 是一个拥有连续就地存储的动态可调整大小数组。类型为 T 的元素被存储并适当对齐在对象内部。内部存储的容量在编译时固定,等于 N。

元素连续存储,这意味着元素不仅可以通过迭代器或随机访问 operator[] 访问,还可以通过指向元素的普通指针的偏移量来访问。指向 inplace_vector 元素的指针可以传递给任何需要指向 C 数组元素的指针的函数。

std::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> 是 可平凡复制 且为空。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 - 元素类型。必须满足 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 和 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]
预留存储空间
(公开静态成员函数)
通过释放未使用的内存来减少内存使用量
(公共静态成员函数)
修饰符
插入元素
(公开成员函数)
插入元素范围
(公开成员函数)
原地构造元素
(公开成员函数)
在末尾就地构造元素
(公开成员函数)
尝试在末尾就地构造元素
(公开成员函数)
无条件在末尾就地构造元素
(公开成员函数)
在末尾添加元素
(公开成员函数)
尝试在末尾添加元素
(公开成员函数)
无条件在末尾添加元素
(公开成员函数)
移除末尾元素
(公开成员函数)
将元素范围添加至末尾
(公开成员函数)
尝试将元素范围添加到末尾
(公开成员函数)
清空内容
(公开成员函数)
擦除元素
(公开成员函数)
交换内容
(公开成员函数)

非成员函数

特化 std::swap 算法
(函数模板)
擦除满足特定条件的所有元素
(函数模板)
按字典序比较两个 inplace_vector 的值
(函数模板)

备注

inplace_vector 中的元素数量可以动态变化,但不超过固定容量,因为元素存储在对象自身内部,类似于 std::array。然而,元素在插入到 inplace_vector 时才会初始化,这与 C 数组或 std::array 不同,后者在实例化时必须构造所有元素。

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); // 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 功能。