C++ STL Containers

vector, map & the STL

The Standard Template Library gives you fast, type-safe containers so you rarely need raw arrays or manual memory. These are the workhorses of competitive programming and interviews.

C++20 ✓ Core Concepts 4 Topics
01

vector — the Default Container

std::vector is a resizable array that manages its own memory. It's the container you reach for by default — contiguous storage, O(1) random access, and amortized O(1) append.

C++ — vector
#include <vector>
#include <algorithm>

std::vector<int> nums = {5, 2, 8, 1};
nums.push_back(9);        // append — [5,2,8,1,9]
nums.pop_back();          // remove last
nums[0];                 // 5 — no bounds check
nums.at(0);              // 5 — throws if out of range
nums.size();              // 4

// sort with the STL algorithm
std::sort(nums.begin(), nums.end());   // [1,2,5,8]

// iterate without copying
for (const auto& n : nums) std::cout << n;

// reserve capacity up front to avoid reallocations
nums.reserve(1000);
vec[i] does no bounds checking — an out-of-range index is undefined behavior (often a silent memory bug). Use vec.at(i) when you want a thrown exception instead.
02

string

std::string is a managed, resizable character sequence — a huge upgrade over C's raw char*. It owns its memory and handles growth for you.

C++ — string
#include <string>

std::string s = "Hello";
s += ", world";         // concatenation, resizes automatically
s.length();             // 12
s.substr(0, 5);         // "Hello"
s.find("world");       // 7 (index), or std::string::npos if absent
s[0];                  // 'H'

// build strings efficiently in a loop with += (no per-step copy)
std::string out;
for (int i = 0; i < 3; i++) out += std::to_string(i);   // "012"
03

map & unordered_map

std::map keeps keys sorted (O(log n), a red-black tree). std::unordered_map is a hash table with O(1) average lookup but no ordering. Pick unordered when you don't need sorted keys.

C++ — map
#include <map>
#include <unordered_map>

std::unordered_map<std::string, int> scores;
scores["alice"] = 95;      // insert or update
scores["bob"] = 88;
scores["alice"];             // 95
scores.count("bob");       // 1 — key exists

// count word frequency — the classic idiom
std::unordered_map<std::string, int> freq;
for (const auto& w : words) freq[w]++;   // [] default-constructs to 0

// iterate key/value (structured bindings, C++17)
for (const auto& [name, score] : scores)
    std::cout << name << ": " << score << "\n";
Reading map[missingKey] inserts a default-constructed value (0 for int) rather than failing. Use .count(key) or .find(key) if you only want to check existence without inserting.
04

set & pair

std::set stores unique, sorted values. std::pair and std::tuple bundle a fixed group of values together — handy for returning two things from a function.

C++ — set & pair
#include <set>
#include <utility>

std::set<int> unique = {3, 1, 1, 2, 3};   // {1, 2, 3} — sorted, deduped
unique.insert(5);
unique.count(2);        // 1 — present

// pair — bundle two values
std::pair<std::string, int> p = {"age", 30};
p.first;                 // "age"
p.second;                // 30

// return two values from a function
std::pair<int, int> minmax(std::vector<int>& v) {
    return {*std::min_element(v.begin(), v.end()),
            *std::max_element(v.begin(), v.end())};
}

Quick Quiz

1. The default go-to container in C++ is…
2. vec[i] on an out-of-range index is…
3. std::map keeps its keys…
4. Reading map[missingKey] does what?
5. std::set stores…