STL
advancedPart of Advanced C++
Theory
The Standard Template Library (STL) is a powerful set of C++ template classes and functions that provide common data structures and algorithms. It has three main components: containers, iterators, and algorithms.
Containers Overview
STL containers are data structures that store collections of objects:
| Container | Description | Header |
|-----------|-------------|--------|
| vector | Dynamic array (contiguous memory) | <vector> |
| deque | Double-ended queue | <deque> |
| list | Doubly-linked list | <list> |
| map | Key-value pairs (sorted by key) | <map> |
| set | Unique sorted elements | <set> |
| unordered_map | Key-value pairs (hash table) | <unordered_map> |
| unordered_set | Unique elements (hash table) | <unordered_set> |
| stack | LIFO adapter | <stack> |
| queue | FIFO adapter | <queue> |
| string | Character array with operations | <string> |
Vector
std::vector is a dynamic array that grows automatically:
#include <vector>
vector<int> vec; // Empty vector
vector<int> vec2(10, 5); // 10 elements, all 5
vector<int> vec3 = {1, 2, 3}; // Initializer list
vec.push_back(42); // Add to end
vec.pop_back(); // Remove from end
int size = vec.size(); // Number of elements
bool empty = vec.empty(); // Check if empty
vec.clear(); // Remove all elements
// Access
int first = vec[0]; // Unchecked access
int firstSafe = vec.at(0); // Bounds-checked (throws out_of_range)
int* data = vec.data(); // Raw pointer to underlying array
// Insert/erase
vec.insert(vec.begin() + 1, 99);
vec.erase(vec.begin() + 2);Capacity management:
cout << vec.size(); // Number of elements
cout << vec.capacity(); // Allocated space
vec.reserve(100); // Pre-allocate memory
vec.shrink_to_fit(); // Reduce capacity to fit sizeMap
std::map stores key-value pairs sorted by key:
#include <map>
map<string, int> ages;
ages["Alice"] = 30;
ages["Bob"] = 25;
// Insertion
ages.insert({"Charlie", 35});
ages.emplace("Dave", 28); // More efficient
// Lookup
int age = ages["Alice"]; // Creates entry if missing!
auto it = ages.find("Bob"); // Returns iterator or end()
int count = ages.count("Alice"); // 1 if exists, 0 if not
// Iteration
for (const auto& [name, age] : ages) {
cout << name << ": " << age << endl;
}Use unordered_map for O(1) average lookup (no ordering):
#include <unordered_map>
unordered_map<string, int> scores; // Faster, but not sortedString
std::string provides rich functionality:
#include <string>
string s = "Hello";
s += " World"; // "Hello World"
int len = s.length(); // 11
int size = s.size(); // Also 11
// Substring
string sub = s.substr(0, 5); // "Hello"
size_t pos = s.find("World"); // 6
size_t notFound = s.find("xyz"); // string::npos
// Modification
s.insert(5, " C++"); // "Hello C++ World"
s.replace(6, 3, "Beautiful"); // "Hello Beautiful World"
s.erase(5, 8); // "Hello World"
// Conversion
const char* cstr = s.c_str();
int num = stoi("42");
string str = to_string(3.14);Iterators
Iterators are objects that point to elements in a container, like pointers:
vector<int> vec = {10, 20, 30, 40, 50};
// begin()/end() — forward iteration
for (auto it = vec.begin(); it != vec.end(); ++it) {
cout << *it << " "; // Dereference to get value
}
// rbegin()/rend() — reverse iteration
for (auto it = vec.rbegin(); it != vec.rend(); ++it) {
cout << *it << " "; // 50 40 30 20 10
}
// cbegin()/cend() — const iterators (read-only)
for (auto it = vec.cbegin(); it != vec.cend(); ++it) {
// *it = 99; // Error! Read-only
}Iterator categories:
- Input iterators: Read once, forward only (istream_iterator)
- Output iterators: Write once, forward only (ostream_iterator)
- Forward iterators: Read/write, forward only (forward_list)
- Bidirectional iterators: Forward and backward (list, set, map)
- Random access iterators: Direct element access (vector, deque, string)
Algorithms
STL provides many algorithms in <algorithm>:
#include <algorithm>
#include <numeric>
vector<int> v = {5, 2, 8, 1, 9, 3, 7, 4, 6};
// Sorting
sort(v.begin(), v.end()); // Ascending
sort(v.begin(), v.end(), greater<int>()); // Descending
// Searching
auto it = find(v.begin(), v.end(), 5); // Find 5
bool exists = binary_search(v.begin(), v.end(), 5); // Sorted range
// Modifying
reverse(v.begin(), v.end()); // Reverse in place
copy(v.begin(), v.end(), vec2.begin()); // Copy to another
fill(v.begin(), v.end(), 0); // Fill with 0
// Min/Max
int minVal = *min_element(v.begin(), v.end());
int maxVal = *max_element(v.begin(), v.end());
// Accumulate (in <numeric>)
int sum = accumulate(v.begin(), v.end(), 0);
int product = accumulate(v.begin(), v.end(), 1, multiplies<int>());
// Count
int c = count(v.begin(), v.end(), 3);
// Transform
transform(v.begin(), v.end(), v.begin(),
[](int x) { return x * 2; });Auto and Range-Based For Loops
Modern C++ (C++11+) makes working with containers much easier:
vector<int> vec = {10, 20, 30};
// Range-based for — by value (copies)
for (int x : vec) {
x = 0; // Doesn't modify original
}
// Range-based for — by reference (modifies)
for (int& x : vec) {
x *= 2;
}
// Range-based for — const reference (read-only, efficient)
for (const int& x : vec) {
cout << x << " ";
}
// With auto (recommended)
for (const auto& x : vec) { cout << x << " "; }
// Iterating over a map
map<string, int> m = {{"a", 1}, {"b", 2}};
for (const auto& [key, value] : m) {
cout << key << ": " << value << endl;
}Prefer range-based for loops over index-based loops when you need to iterate over all elements. It's cleaner, less error-prone, and works with all containers.
Practical Examples
When you know the final size of a vector, use reserve() to pre-allocate memory. This avoids repeated reallocations as the vector grows, significantly improving performance.
Exercises
Vector Operations
Create a vector of integers. Fill it with the numbers 1-20. Then: remove all even numbers, double each remaining number, and print the result in reverse order.
Expected Output:
38 34 30 26 22 18 14 10 6 2Map-Based Phone Directory
Create a phone directory using std::map. Implement a program that lets the user add, lookup, and list contacts. Store the data in alphabetical order using the map's natural ordering.
Expected Output:
All contacts:\nAlice: 555-1234\nBob: 555-5678\nCharlie: 555-9012\n\nFinding Alice: 555-1234\nFinding Dave: Not foundString Processing with Algorithms
Write a program that reads a sentence, splits it into words, filters out words shorter than 3 characters, converts remaining words to uppercase, sorts them alphabetically, and removes duplicates.
Expected Output:
Processed words: BAT CAT HAT MAT SAT THE WITHMini Quiz
Mini Quiz
Mini Project
Mini Project: Movie Database with STL
Build a movie database application using STL containers and algorithms. Store movie information, support searching, sorting, and filtering operations.
Requirements:
Bonus Challenge
Add a feature to recommend movies based on a given movie's genres. Implement a simple TF-IDF search over movie descriptions.