deque不是vector替代品,适合首尾频繁增删、少随机访问中间元素的场景;声明初始化有空构造、指定大小初值、迭代器范围构造和初始化列表四种方式。
deque 不是 vector 的替代品,它适合频繁在首尾增删、但不常随机访问中间元素的场景;误用会导致性能意外下降。
如何声明和初始化 deque
deque 是 C++
标准库
中的双端队列容器,头文件为
。它支持在头部和尾部高效插入/删除(均摊 O(1)),但随机访问虽为 O(1),实际缓存局部性不如
。
常见初始化方式:
—— 空 deque
—— 含 5 个值为 42 的元素
—— 从其他容器(如
)迭代器范围构造
—— C++11 起支持初始化列表(注意:不是所有编译器对大列表做优化,小数据量安全)
首尾插入与删除操作必须用对函数
deque 提供四组明确语义的操作函数,混用
和
很常见,但写错名字(比如写成
拼错)会直接编译失败;更隐蔽的问题是误把
当作删除——它只返回引用,不移除元素。
立即学习
“
C++免费学习笔记(深入)
”;
C函数速查手册(CHM版)
C函数速查手册(CHM版)
下载
尾部操作:
、
、
头部操作:
、
、
和
无返回值,调用前必须确保非空,否则行为未定义(不会抛异常)
若需“取并删”,得手动组合:例如
迭代器失效规则比 vector 更宽松,但仍有陷阱
deque 的迭代器在首尾插入/删除时通常不失效(这是它相比
的关键优势),但以下情况仍会失效:
调用
删除中间元素时,被删位置及之后的迭代器全部失效
调用
或移动赋值(
)后,所有迭代器失效
虽然
在首尾插入不使迭代器失效,但在中间插入(如
)可能导致部分迭代器失效(标准未保证,各实现不同,应避免依赖)
实践中,只要坚持“只在两端增删”,基本可放心使用迭代器遍历。
什么时候不该用 deque
deque 内部通常以分段连续内存块实现(如 chunk 数组),这带来额外指针跳转开销。以下情况建议换用其他容器:
需要大量随机访问(如频繁
且
分布广泛)→ 改用
内存极度受限或要求严格连续布局(如对接 C API)→
或裸数组
仅需单端操作(如只在尾部 push/pop)→
更轻量,且现代编译器对其
优化极好
要存储大型对象且频繁移动 → 注意
的移动构造/赋值虽为 O(1),但析构旧元素仍需逐个调用,可能比预期慢
真正发挥 deque 价值的典型场景是:滑动窗口、BFS 队列、撤销栈(支持从头加新操作、从尾撤回)——这些都天然契合“两端活跃、中间静态”的访问模式。
vectorstd::deque dq; std::deque dq(5, 42); std::deque dq(v.begin(), v.end()); vectorstd::deque dq = {1, 2, 3}; push_backpop_frontpush_front()front()push_back()pop_back()back()push_front()pop_front()front()pop_front()pop_back()auto x = dq.front(); dq.pop_front();vectorerase()clear()dq = std::move(other)insert()dq.insert(dq.begin() + 3, 99)dq[i]ivectorvectorvectorpush_back()deque