C++ STL Containers
vector
Dynamic array — the default container
#include <vector>
std::vector<int> nums = {1, 2, 3, 4, 5};
nums.push_back(6);
nums.emplace_back(7); // construct in place (avoids copy)
// Access
nums[0]; // unchecked (UB if out of bounds)
nums.at(0); // checked (throws std::out_of_range)
nums.front(); // first element
nums.back(); // last element
// Size and capacity
nums.size(); // number of elements
nums.capacity(); // allocated storage
nums.reserve(100); // pre-allocate (avoids reallocations)
// Iterate
for (const auto& n : nums) {
std::cout << n << " ";
}
// Erase-remove idiom
nums.erase(std::remove(nums.begin(), nums.end(), 3), nums.end());
vector is contiguous memory — cache-friendly and fast for sequential access. Use reserve when you know the size ahead of time to avoid reallocations.
map and unordered_map
Sorted map (tree) vs hash map
#include <map>
#include <unordered_map>
// std::map — sorted by key (red-black tree), O(log n) lookup
std::map<std::string, int> ports = {
{"ssh", 22},
{"http", 80},
{"https", 443},
};
// std::unordered_map — hash table, O(1) average lookup
std::unordered_map<std::string, int> fast_ports;
fast_ports["ssh"] = 22;
fast_ports.insert({"http", 80});
// Access
ports["ssh"]; // 22 (creates entry if missing!)
ports.at("ssh"); // 22 (throws if missing)
// Check existence
if (auto it = ports.find("ssh"); it != ports.end()) {
std::cout << it->second << std::endl;
}
// C++20: contains
if (ports.contains("ssh")) { ... }
// Iterate
for (const auto& [name, port] : ports) {
std::cout << name << ": " << port << std::endl;
}
operator[] on a map inserts a default-constructed value if the key is missing. Use find() or at() to avoid accidental insertions.
set and unordered_set
Unique element collections
#include <set>
std::set<std::string> seen;
seen.insert("10.50.1.1");
seen.insert("10.50.1.2");
seen.insert("10.50.1.1"); // no-op — already present
std::cout << seen.size(); // 2
if (seen.count("10.50.1.1")) {
std::cout << "already seen" << std::endl;
}
array
Fixed-size array with bounds checking
#include <array>
std::array<int, 5> arr = {1, 2, 3, 4, 5};
arr.at(0); // checked access
arr.size(); // 5
arr.fill(0); // set all to 0
std::array is a stack-allocated, fixed-size container. Prefer it over C-style arrays — it has .size(), .at(), and works with STL algorithms.
string
String operations
#include <string>
std::string s = "hello, world";
s.find("world"); // 7
s.substr(0, 5); // "hello"
s.replace(0, 5, "hi"); // "hi, world"
s.starts_with("hi"); // true (C++20)
s.ends_with("ld"); // true (C++20)
// Split (no built-in — use stringstream)
#include <sstream>
std::istringstream iss("10.50.1.1 22 ssh");
std::string host, port_str, service;
iss >> host >> port_str >> service;
Algorithms
STL algorithms work with all containers
#include <algorithm>
#include <numeric>
std::vector<int> v = {5, 2, 8, 1, 9, 3};
std::sort(v.begin(), v.end()); // ascending
std::sort(v.begin(), v.end(), std::greater<int>()); // descending
auto it = std::find(v.begin(), v.end(), 8);
bool found = (it != v.end());
int sum = std::accumulate(v.begin(), v.end(), 0);
bool all_positive = std::all_of(v.begin(), v.end(), [](int n) { return n > 0; });
auto [min, max] = std::minmax_element(v.begin(), v.end());
// Transform — apply function to each element
std::vector<int> doubled(v.size());
std::transform(v.begin(), v.end(), doubled.begin(), [](int n) { return n * 2; });
Algorithms operate on iterator ranges [begin, end). C++20 introduces std::ranges::sort(v) — no more .begin()/.end().