stack & queue
std::stack, std::queue, and std::priority_queue provide the classic LIFO, FIFO, and priority-ordered access patterns. Unlike vector, list, or map, none of these are standalone containers — they are container adaptors: thin wrappers that restrict the interface of an underlying container (by default deque or vector) down to a small, focused set of operations.
std::stack — LIFO (last in, first out)
A stack only lets you interact with one end. You push elements on and pop them off in reverse order — the last one pushed is the first one popped.
stack_basics.cpp
CPP
#include <stack>
#include <iostream>
int main() {
std::stack<int> s;
s.push(10);
s.push(20);
s.push(30);
std::cout << s.top() << std::endl; // 30 — most recently pushed
s.pop(); // removes 30
std::cout << s.top() << std::endl; // 20
std::cout << s.size() << std::endl; // 2
return 0;
}std::queue — FIFO (first in, first out)
A queue only lets you add at the back and remove from the front — the first element pushed is the first one popped, exactly like a real-world line.
queue_basics.cpp
CPP
#include <queue>
#include <iostream>
int main() {
std::queue<int> q;
q.push(10);
q.push(20);
q.push(30);
std::cout << q.front() << std::endl; // 10 — first one in
std::cout << q.back() << std::endl; // 30 — most recent
q.pop(); // removes 10
std::cout << q.front() << std::endl; // 20
return 0;
}std::priority_queue — always-sorted access to the largest element
A priority queue keeps its elements ordered so that .top() always returns the largest element by default (a “max-heap”). Both push and pop run in O(log n) time.
priority_queue_basics.cpp
CPP
#include <queue>
#include <iostream>
int main() {
std::priority_queue<int> pq;
pq.push(30);
pq.push(10);
pq.push(50);
pq.push(20);
// Popping always yields elements largest-first.
while (!pq.empty()) {
std::cout << pq.top() << " "; // 50 30 20 10
pq.pop();
}
std::cout << std::endl;
return 0;
}To get a min-heap instead (smallest element on top), supply a custom comparator — the standard trick is std::greater<T> in place of the default std::less<T>.
priority_queue_min_heap.cpp
CPP
#include <queue>
#include <vector>
#include <iostream>
int main() {
// Template args: element type, underlying container, comparator.
std::priority_queue<int, std::vector<int>, std::greater<int>> minHeap;
minHeap.push(30);
minHeap.push(10);
minHeap.push(50);
while (!minHeap.empty()) {
std::cout << minHeap.top() << " "; // 10 30 50
minHeap.pop();
}
std::cout << std::endl;
return 0;
}These are adaptors, not independent containers
stack defaults to wrapping a deque; queue also defaults to deque; priority_queue defaults to wrapping a vector arranged as a binary heap. You can override the underlying container as a second template argument (as shown for the min-heap example above) as long as it supports the operations the adaptor needs. This is a good example of composition in the STL's design — new behavior is built by restricting and recombining existing containers, not by writing new data structures from scratch.
std::stack— LIFO:.push(),.pop(),.top().std::queue— FIFO:.push(),.pop(),.front(),.back().std::priority_queue— max-heap by default:.top()is always the largest element; passstd::greater<T>for a min-heap.All three are container adaptors, built on top of
dequeorvector, not standalone data structures.