Lesson 43
Queue
Covers creating a queue, characteristics of queues, common queue operations, how a queue works internally, and processing elements in FIFO order.
Lesson content
What is STL Queue in C++?
A queue is a container adapter in the Standard Template Library (STL) that stores elements in FIFO (First In, First Out) order.
This means the first element inserted is the first element removed.
Think of a queue as a line at a ticket counter. The first person to join the line is the first one served, while new people join at the back.
Unlike std::vector or std::deque, a queue restricts how elements are accessed. You can only insert at the back and remove from the front. This restriction makes queues simple and efficient for sequential processing.
Why does STL Queue exist?
Many real-world applications process data in arrival order. Instead of implementing FIFO logic manually, C++ provides std::queue.
- Printer jobs
- Customer service systems
- CPU task scheduling
- Network packet processing
- Breadth-First Search (BFS)
- Message queues
Real-world use cases
- Printer job management
- Call center systems
- Operating system scheduling
- Breadth-First Search (BFS)
- Web server request handling
- Banking queues
- Traffic management systems
- Multiplayer game event processing
Prerequisites
- Variables and data types
- Arrays
- Functions
- Loops
- Templates
- Basic STL containers (vector and deque)
Including the header
#include <queue>Creating a queue
queue<data_type> queue_name;
// Example:
queue<int> numbers;Characteristics of STL Queue
- Access method: FIFO (First In, First Out)
- Front insertion: not allowed
- Back insertion: allowed
- Front removal: allowed
- Random access: not supported
- Default underlying container: std::deque
Common queue operations
- push() – add an element to the back
- pop() – remove the front element
- front() – access the first element
- back() – access the last element
- size() – number of elements
- empty() – check whether the queue is empty
How a queue works
Suppose we insert 10, 20, 30. The queue looks like: Front → 10 20 30 ← Back. Calling pop() removes 10, leaving Front → 20 30 ← Back. The queue always removes the oldest element.
Underlying container
By default, std::queue uses std::deque internally. You can also use std::list.
queue<int, list<int>> q;Example 1: Creating and displaying a queue
#include <iostream>
#include <queue>
using namespace std;
int main()
{
queue<int> numbers;
numbers.push(10);
numbers.push(20);
numbers.push(30);
cout << numbers.front();
return 0;
}
// Output: 10Example 2: Removing elements
#include <iostream>
#include <queue>
using namespace std;
int main()
{
queue<int> values;
values.push(100);
values.push(200);
values.push(300);
values.pop();
cout << values.front();
return 0;
}
// Output: 200Example 3: Processing all elements
#include <iostream>
#include <queue>
using namespace std;
int main()
{
queue<int> numbers;
numbers.push(1);
numbers.push(2);
numbers.push(3);
while (!numbers.empty())
{
cout << numbers.front();
cout << " ";
numbers.pop();
}
return 0;
}
// Output: 1 2 3Example 4: Breadth-first search style processing
#include <iostream>
#include <queue>
using namespace std;
int main()
{
queue<int> tasks;
tasks.push(101);
tasks.push(102);
tasks.push(103);
while (!tasks.empty())
{
cout << "Processing Task ";
cout << tasks.front();
cout << endl;
tasks.pop();
}
return 0;
}
// Output:
// Processing Task 101
// Processing Task 102
// Processing Task 103Example 5: Printer queue
#include <iostream>
#include <queue>
#include <string>
using namespace std;
int main()
{
queue<string> printQueue;
printQueue.push("Report.pdf");
printQueue.push("Invoice.docx");
printQueue.push("Presentation.ppt");
while (!printQueue.empty())
{
cout << "Printing: ";
cout << printQueue.front();
cout << endl;
printQueue.pop();
}
return 0;
}Common mistakes and pitfalls
- Trying to access elements with q[0]. Fix: use front() and back()
- Calling front() on an empty queue. Fix: check empty() first
- Forgetting that pop() doesn't return the removed element. Fix: call front() before pop()
- Using a queue when random access is required. Fix: use std::vector or std::deque
- Expecting iteration support. Fix: a queue does not provide iterators
Best practices
- Always check empty() before calling front() or pop()
- Use queues for FIFO processing only
- Process elements using a while (!queue.empty()) loop
- Store lightweight objects or use pointers/smart pointers for large objects
- Choose the appropriate underlying container if needed (the default std::deque is suitable for most cases)
When not to use this
- Random access is required (std::vector is better)
- LIFO behavior is needed (use std::stack)
- Elements must remain sorted (use std::priority_queue or std::set)
- Frequent middle insertions or deletions are required (use std::list)
- You need to iterate through all elements without removing them
Summary
- STL Queue in C++ is a FIFO (First In, First Out) container adapter
- Elements are inserted at the back using push()
- Elements are removed from the front using pop()
- Access the first element using front() and the last element using back()
- Common operations include push(), pop(), front(), back(), size(), and empty()
- A queue does not support random access or iterators
- Use std::queue whenever data must be processed in the order it arrives
Frequently asked questions
What is the difference between a queue and a deque?
A deque is a full container that allows insertion, deletion, and random access. A queue is a container adapter that restricts access to FIFO operations, typically using a deque internally.
Why doesn't pop() return the removed element?
The STL separates access and removal. You should first retrieve the front element using front(), then call pop() to remove it.
Can I iterate through a queue?
No. std::queue does not provide iterators. To process all elements, repeatedly access front() and remove it with pop() until the queue is empty.
What is the time complexity of queue operations?
For the default underlying std::deque, push(), pop(), front(), and back() are all O(1).
When should I use std::queue instead of std::deque?
Use std::queue when you want to enforce FIFO behavior and prevent accidental random access or insertion/removal from arbitrary positions. Use std::deque when you need more flexibility while still benefiting from efficient operations at both ends.