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().