Namespaces
Variants

std:: inplace_vector

From cppreference.net
定义于头文件 <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_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]
预留存储空间
(公开静态成员函数)
通过释放未使用的内存来减少内存使用量
(公共静态成员函数)
修饰符
插入元素
(公开成员函数)
插入元素范围
(公开成员函数)
原地构造元素
(公开成员函数)
在末尾就地构造元素
(公开成员函数)
尝试在末尾就地构造元素
(公开成员函数)
无条件在末尾就地构造元素
(公开成员函数)
在末尾添加元素
(公开成员函数)
尝试在末尾添加元素
(公开成员函数)
无条件在末尾添加元素
(公开成员函数)
移除末尾元素
(公开成员函数)
将元素范围添加至末尾
(公开成员函数)
尝试将元素范围添加到末尾
(公开成员函数)
清空内容
(公开成员函数)
擦除元素
(公开成员函数)
交换内容
(公开成员函数)

非成员函数

特化 std::swap 算法
(函数模板)
擦除满足特定条件的所有元素
(函数模板)
按字典序比较两个 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 功能。