Windows热键侦探:揭秘系统快捷键冲突的神秘面纱
2026/5/22 10:10:34
STL 中的stack和queue并不是独立新建的容器类,而是“容器适配器”:对底层容器接口的一层封装(包装),把底层容器暴露的接口变成特定的“栈/队列”接口。
默认情况下,STL 的stack和queue使用deque作为底层容器,因为deque在头尾操作和随机访问之间提供了折中性能。
适配器的作用是“将一个类的接口转换为客户希望的另一个接口”。stack:只允许在一端插入/删除;queue:允许在一端入、一端出(FIFO)。
适配器并不自己管理内存,而是复用底层容器(deque,vector,list等)。
vectorlist(双向链表)dequestack/queue默认容器。复杂度速览(常见操作)
vectorO(1) 摇摆(扩容摊销)、dequeO(1)、listO(1)dequeO(1)、listO(1)、vectorO(n)vectorO(1)、deque接近 O(1)、listO(n)stack适配器要点与常见错误template<class T, class Container = deque<T>>const与noexcept:比如top()、size()、empty()应该标记为const(不改变对象状态),size()/empty()可标记noexcept。top()返回引用:应返回const T&或T&取决于用途,通常提供const版本和非常量版本。top()/pop()是未定义行为(与 STL 一致);可以在包装层增加断言或抛出异常以增强调试信息。using container_type = Container; using value_type = T;有助于与 STL 接口兼容。改进后的stack参考实现
namespacesqtque{// 用 Container 适配转换出 stacktemplate<classT,classContainer=std::deque<T>>classstack{public:usingvalue_type=T;usingcontainer_type=Container;usingsize_type=std::size_t;// 默认构造 / 析构由底层容器负责voidpush(constT&x){_con.push_back(x);}voidpush(T&&x){_con.push_back(std::move(x));}voidpop(){assert(!empty()&&"pop on empty stack");_con.pop_back();}T&top(){assert(!empty()&&"top on empty stack");return_con.back();}constT&top()const{assert(!empty()&&"top on empty stack");return_con.back();}size_typesize()constnoexcept{return_con.size();}boolempty()constnoexcept{return_con.empty();}private:Container _con;// 封装出一个容器};}#include<iostream>#include<vector>intmain(){sqtque::stack<int>s;// 默认使用 deque<int>s.push(1);s.push(2);std::cout<<s.top()<<'\n';// 2s.pop();std::cout<<s.top()<<'\n';// 1// 使用 vector 作为底层容器(可行,但 vector 不支持 push_front)sqtque::stack<int,std::vector<int>>sv;sv.push(10);std::cout<<sv.top()<<'\n';return0;}top()/pop()在空容器上未定义行为,最好在调试或库接口中显式检查或断言。std::stack完全兼容,考虑添加构造重载(接受容器参数)和访问底层容器的成员函数(如c())。vector;若需要稳定的头尾 O(1),用deque;若频繁在中间插入删除且已持有迭代器,考虑list。理解容器适配器的核心在于“接口的封装”和“底层容器的选择”。实现时应注意模板默认参数写法、成员函数的 const/ noexcept 语义与空容器的边界条件。通过上述改进可以让自实现的stack更安全、更 STL 风格、更易于扩展。