Namespaces
Variants

std:: deque

From cppreference.net
定义于头文件 <deque>
template <

class T,
class Allocator = std:: allocator < T >

> class deque ;
(1)
namespace pmr {

template < class T >
using deque = std :: deque < T, std:: pmr :: polymorphic_allocator < T >> ;

}
(2) (C++17 起)

std::deque (双端队列)是一种支持快速在首尾两端进行插入和删除操作的索引序列容器。此外,在双端队列任意一端进行插入和删除操作均不会导致指向其余元素的指针或引用失效。

std::vector 不同,deque 的元素并非连续存储:典型实现使用一系列单独分配的固定大小数组,并附带额外的簿记信息。这意味着对 deque 进行索引访问需要执行两次指针解引用,而 vector 的索引访问仅需执行一次。

deque的存储空间会根据需要自动扩展和收缩。deque的扩展比 std::vector 的扩展更廉价,因为它不需要将现有元素复制到新的内存位置。另一方面,deque通常具有较大的最小内存开销;一个仅包含单个元素的deque也必须分配其完整的内部数组(例如在64位libstdc++上为对象大小的8倍;在64位libc++上为对象大小的16倍或4096字节中的较大值)。

双端队列常见操作的复杂度(效率)如下:

  • 随机访问 - 常数时间复杂度 O(1)
  • 在末尾或开头插入/删除元素 - 常数时间复杂度 O(1)
  • 在中间位置插入/删除元素 - 线性时间复杂度 O(n)

std::deque 满足 Container AllocatorAwareContainer SequenceContainer ReversibleContainer 的要求。

std::deque 的所有成员函数均为 constexpr :可以在常量表达式求值过程中创建和使用 std::deque 对象。

然而, std::deque 对象通常不能是 constexpr 的,因为任何动态分配的存储必须在同一常量表达式求值过程中释放。

(自 C++26 起)

目录

模板参数

T - 元素的类型。
T 必须满足 CopyAssignable CopyConstructible 的要求。 (C++11 前)
对元素的要求取决于容器实际执行的操作。通常要求元素类型为完整类型且满足 Erasable 的要求,但许多成员函数会施加更严格的要求。 (C++11 起)

Allocator - 用于获取/释放内存及构造/销毁其中元素的分配器。该类型必须满足 Allocator 的要求。 (C++20 前) (C++20 起) Allocator::value_type T 不同,则 行为未定义 程序非良构

迭代器失效

操作 迭代器失效情况
所有只读操作 永不失效
swap , std::swap 尾后迭代器可能失效(具体实现定义)
shrink_to_fit , clear , insert ,
emplace , push_front , push_back ,
emplace_front , emplace_back
始终失效
erase 在首部删除时 - 仅被删除元素失效

在尾部删除时 - 仅被删除元素和尾后迭代器失效
其他情况 - 所有迭代器失效

尾后迭代器何时失效未作规定

(C++11 前)

尾后迭代器也会失效,除非被删除元素位于容器首部
且最后一个元素未被删除

(C++11 起)
resize 新尺寸小于原尺寸时 - 仅被删除元素和尾后迭代器失效

新尺寸大于原尺寸时 - 所有迭代器失效
其他情况 - 无迭代器失效

pop_front , pop_back 指向被删除元素的迭代器失效

尾后迭代器可能失效(具体实现定义)

(C++11 前)

尾后迭代器也会失效

(C++11 起)

失效说明

成员类型

成员类型 定义
value_type T
allocator_type Allocator
size_type 无符号整数类型(通常为 std::size_t
difference_type 有符号整数类型(通常为 std::ptrdiff_t
reference value_type &
const_reference const value_type &
pointer

Allocator::pointer

(C++11 前)

std:: allocator_traits < Allocator > :: pointer

(C++11 起)
const_pointer

Allocator::const_pointer

(C++11 前)

std:: allocator_traits < Allocator > :: const_pointer

(C++11 起)
iterator LegacyRandomAccessIterator ConstexprIterator (C++26 起) 指向 value_type
const_iterator LegacyRandomAccessIterator ConstexprIterator (C++26 起) 指向 const value_type
reverse_iterator std:: reverse_iterator < iterator >
const_reverse_iterator std:: reverse_iterator < const_iterator >

成员函数

构造 deque
(公开成员函数)
销毁 deque
(公开成员函数)
为容器赋值
(公开成员函数)
为容器赋值
(公开成员函数)
将值范围赋值给容器
(公开成员函数)
返回关联的分配器
(公开成员函数)
元素访问
访问指定元素(带边界检查)
(公开成员函数)
访问指定元素
(公开成员函数)
访问首元素
(公开成员函数)
访问最后一个元素
(公开成员函数)
迭代器
返回指向起始位置的迭代器
(公开成员函数)
(C++11)
返回指向末尾的迭代器
(公开成员函数)
返回指向起始位置的反向迭代器
(公开成员函数)
(C++11)
返回指向末尾的反向迭代器
(公开成员函数)
容量
检查容器是否为空
(公开成员函数)
返回元素数量
(公开成员函数)
返回可能容纳的最大元素数
(公开成员函数)
通过释放未使用的内存来减少内存使用量
(公开成员函数)
修饰符
清空内容
(公开成员函数)
插入元素
(公开成员函数)
插入一个元素范围
(公开成员函数)
(C++11)
原地构造元素
(公开成员函数)
擦除元素
(公开成员函数)
在末尾添加元素
(公开成员函数)
在容器末尾就地构造元素
(公开成员函数)
在末尾添加一个元素范围
(公开成员函数)
移除末尾元素
(公开成员函数)
在起始位置插入元素
(公开成员函数)
在容器头部就地构造元素
(公开成员函数)
在开头添加一系列元素
(公开成员函数)
移除首元素
(公开成员函数)
改变存储的元素数量
(公开成员函数)
交换内容
(公开成员函数)

非成员函数

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

推导指引

(C++17 起)

注释

功能测试 标准 功能
__cpp_lib_containers_ranges 202202L (C++23) 容器的范围构造与插入
__cpp_lib_constexpr_deque 202502L (C++26) constexpr std::deque

示例

#include <deque>
#include <iostream>
int main()
{
    // 创建包含整数的双端队列
    std::deque<int> d = {7, 5, 16, 8};
    // 在双端队列的开头和末尾添加整数
    d.push_front(13);
    d.push_back(25);
    // 遍历并输出双端队列的值
    for (int n : d)
        std::cout << n << ' ';
    std::cout << '\n';
}

输出:

13 7 5 16 8 25

缺陷报告

以下行为变更缺陷报告被追溯应用于先前发布的C++标准。

DR 适用版本 发布行为 正确行为
LWG 230 C++98 T 未被要求必须是 CopyConstructible
(可能无法构造类型为 T 的元素)
T 同时需要
满足 CopyConstructible

另请参阅

适配容器以提供队列(FIFO数据结构)
(类模板)