Backend Systemsbeginner
C++ STL: Containers, Algorithms & Iterators
Master the C++ Standard Template Library: vector, map, set, unordered_map, and 30+ algorithms. Learn to write expressive, efficient C++ with STL.
Asma HafeezApril 17, 20265 min read
cppstlcontainersalgorithmsiterators
C++ STL: Containers, Algorithms & Iterators
The STL gives you battle-tested, efficient data structures and algorithms. Using it well is what separates good C++ from great C++.
vector — Dynamic Array
CPP
#include <vector>
#include <algorithm>
std::vector<int> v = {3, 1, 4, 1, 5, 9};
// Access
v[0]; // 3 — no bounds check
v.at(0); // 3 — throws std::out_of_range if invalid
v.front(); // 3
v.back(); // 9
// Modify
v.push_back(2); // add to end
v.pop_back(); // remove from end
v.insert(v.begin(), 0); // insert at front (slow for large vectors)
v.erase(v.begin()); // remove first element
// Size
v.size(); // current count
v.capacity(); // allocated space (may be more than size)
v.reserve(100); // pre-allocate — avoids reallocations
v.empty(); // true if size == 0
v.clear(); // remove all elements
// Iterate
for (int x : v) std::cout << x << " "; // range-for
for (auto it = v.begin(); it != v.end(); ++it) *it *= 2; // iterator
// Sort
std::sort(v.begin(), v.end()); // ascending
std::sort(v.begin(), v.end(), std::greater<int>()); // descending
std::sort(v.begin(), v.end(), [](int a, int b){ return a > b; }); // lambdamap and unordered_map
CPP
#include <map>
#include <unordered_map>
// map — ordered by key (binary tree), O(log n) operations
std::map<std::string, int> scores;
scores["Alice"] = 95;
scores["Bob"] = 87;
scores["Carol"] = 92;
scores.at("Alice"); // 95 — throws if not found
scores.count("Dave"); // 0 — not found
scores.contains("Bob"); // true (C++20)
scores.erase("Carol");
for (const auto& [name, score] : scores) { // structured binding
std::cout << name << ": " << score << "\n";
}
// unordered_map — hash table, O(1) average, no ordering
std::unordered_map<std::string, int> fast_scores;
fast_scores["Alice"] = 95;
// Safe access with default
int s = fast_scores.count("Dave") ? fast_scores["Dave"] : 0;
// Or:
auto it = fast_scores.find("Dave");
if (it != fast_scores.end()) std::cout << it->second;set and unordered_set
CPP
#include <set>
#include <unordered_set>
std::set<int> unique = {5, 3, 1, 4, 1, 5}; // {1, 3, 4, 5} — sorted, no dupes
unique.insert(2); // {1, 2, 3, 4, 5}
unique.erase(3); // {1, 2, 4, 5}
unique.count(4); // 1 (exists)
unique.contains(10); // false (C++20)
// Set intersection
std::set<int> a = {1, 2, 3, 4};
std::set<int> b = {2, 4, 6};
std::set<int> intersection;
std::set_intersection(a.begin(), a.end(), b.begin(), b.end(),
std::inserter(intersection, intersection.begin()));
// intersection = {2, 4}Other Containers
CPP
#include <list>
#include <deque>
#include <queue>
#include <stack>
// list — doubly linked list, O(1) insert/erase anywhere
std::list<int> lst = {1, 2, 3};
lst.push_front(0);
lst.push_back(4);
// deque — double-ended queue, O(1) push/pop at both ends
std::deque<int> dq = {1, 2, 3};
dq.push_front(0);
dq.push_back(4);
// queue — FIFO
std::queue<std::string> q;
q.push("first");
q.push("second");
std::string front = q.front(); // "first"
q.pop();
// stack — LIFO
std::stack<int> s;
s.push(1); s.push(2); s.push(3);
s.top(); // 3
s.pop(); // removes 3STL Algorithms
All in #include <algorithm>.
CPP
#include <algorithm>
#include <numeric>
#include <vector>
std::vector<int> v = {3, 1, 4, 1, 5, 9, 2, 6};
// Search
auto it = std::find(v.begin(), v.end(), 4); // iterator to 4
bool found = std::binary_search(v.begin(), v.end(), 4); // requires sorted!
int cnt = std::count(v.begin(), v.end(), 1); // 2
// Sort
std::sort(v.begin(), v.end());
std::stable_sort(v.begin(), v.end()); // preserves equal order
std::nth_element(v.begin(), v.begin()+3, v.end()); // 4th element in place
// Transform
std::vector<int> doubled(v.size());
std::transform(v.begin(), v.end(), doubled.begin(),
[](int x) { return x * 2; });
// Accumulate / reduce
int sum = std::accumulate(v.begin(), v.end(), 0);
int prod = std::accumulate(v.begin(), v.end(), 1, std::multiplies<int>());
// Min/Max
auto minIt = std::min_element(v.begin(), v.end());
auto maxIt = std::max_element(v.begin(), v.end());
auto [mn, mx] = std::minmax_element(v.begin(), v.end());
// Copy / filter
std::vector<int> evens;
std::copy_if(v.begin(), v.end(), std::back_inserter(evens),
[](int x) { return x % 2 == 0; });
// Remove-erase idiom (removes 1s from vector)
v.erase(std::remove(v.begin(), v.end(), 1), v.end());
// Reverse and rotate
std::reverse(v.begin(), v.end());
std::rotate(v.begin(), v.begin() + 2, v.end()); // rotate left by 2
// Check predicates
bool allPos = std::all_of(v.begin(), v.end(), [](int x){ return x > 0; });
bool anyBig = std::any_of(v.begin(), v.end(), [](int x){ return x > 100; });
bool noneNeg= std::none_of(v.begin(), v.end(),[](int x){ return x < 0; });String Operations
CPP
#include <string>
#include <sstream>
std::string s = "Hello, World!";
s.length(); // 13
s.substr(0, 5); // "Hello"
s.find("World"); // 7
s.replace(7, 5, "C++"); // "Hello, C++!"
s + " More"; // concatenation
// Split string by delimiter
std::vector<std::string> split(const std::string& s, char delim) {
std::vector<std::string> result;
std::stringstream ss(s);
std::string token;
while (std::getline(ss, token, delim)) {
result.push_back(token);
}
return result;
}
auto parts = split("a,b,c,d", ',');
// {"a", "b", "c", "d"}
// Convert
int n = std::stoi("42");
double d = std::stod("3.14");
std::string str = std::to_string(42);Ranges (C++20)
C++20 ranges make pipelines more readable.
CPP
#include <ranges>
#include <vector>
std::vector<int> v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
// Filter even numbers, square them, take first 3
auto result = v
| std::views::filter([](int x){ return x % 2 == 0; })
| std::views::transform([](int x){ return x * x; })
| std::views::take(3);
for (int x : result) std::cout << x << " "; // 4 16 36Key Takeaways
- Use
vectorby default — it's the fastest for sequential data unordered_mapfor fast lookup;mapwhen you need sorted iteration- Range-for (
for (auto& x : container)) is cleaner than iterator loops - STL algorithms are tested, optimized, and expressive — don't write your own loops when
std::sort,std::find, orstd::transformwill do - C++20 ranges make functional pipelines first-class — use them in new code
Enjoyed this article?
Explore the Backend Systems learning path for more.
Found this helpful?
Leave a comment
Have a question, correction, or just found this helpful? Leave a note below.