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 > 满足 可平凡复制 要求且为空。 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