直接说结论:std::deque 是 C++ 标准库中支持高效两端插入/删除的序列容器,比 std::vector 多出 push_front() 和 pop_front(),但随机访问性能略弱于 vector(常数因子稍大,仍为 O(1))。
必须包含头文件 ,且所有操作都依赖模板参数类型。常见误写是漏掉命名空间或用错尖括号语法。
std::deque dq;
std::deque dq(5); → 含
5 个 0
std::deque dq(5, 42); → 含 5 个 42
int arr[] = {1, 2, 3}; std::deque dq(arr, arr + 3);
std::deque<:string> dq = {"a", "b", "c"};
deque 的核心价值就在前后操作都是 O(1) 均摊复杂度,但要注意:没有 insert_front() 这种函数,只有 push_front() 和 pop_front();pop_front() 不返回值,取值需先用 front()。
dq.push_front(10);
dq.push_back(20);
dq.pop_front();(不返回元素,删前请先 if (!dq.empty()) x = dq.front();)dq.pop_back();
dq.front()、dq.back() —— 若容器为空,行为未定义(不是抛异常,是崩溃或脏读)std::dequedq = {1, 2, 3}; dq.push_front(0); // dq → {0,1,2,3} dq.push_back(4); // dq → {0,1,2,3,4} dq.pop_front(); // dq → {1,2,3,4} dq.pop_back(); // dq → {1,2,3}
deque 支持随机访问(dq[i]、dq.at(i)),也支持所有标准迭代器操作,但它的内存不连续 —— 实际由多个固定大小缓冲区组成。这导致两个隐性影响:
&dq[0] + i != &dq[i]:指针算术不成立,不能把 dq.data() 当作 C 数组传给需要连续内存的 API(vector 可以,deque 不行)vector 宽松:仅在对应端插入/删除时,另一端的迭代器仍有效;但中间插入(insert(pos, ...))会导致所有迭代器失效at() 会做边界检查并抛 std::out_of_range,operator[] 不检查 —— 和 vector 行为一致选 deque 不是因为“它两头快”,而是因为你的场景同时满足:需要频繁在两端增删 + 需要较快的随机访问 + 不要求内存连续。
滑动窗口最大值、实现栈+队列混合结构、日志缓冲区(头进尾出或尾进头出)
需要传给 OpenGL 的顶点数组(要 vector::data())、99% 时间只在尾部操作(用 vector 更缓存友好)、频繁在中间插入/删除(改用 list 或 forward_list)deque 构造/析构单个元素的开销略高于 vector(因涉及缓冲区管理),元素类型很重时(如含大数组的 struct)要实测最容易被忽略的一点:deque 的 size() 是 O(1),但某些老编译器(如早期 MSVC)实现曾是 O(n),现在主流 STL(libstdc++、libc++、MSVC STL)均已保证 O(1)。不过,如果你在嵌入式环境或自研 STL 上使用,务必查证文档。