Skip to main content
STL Containers

The Standard Template Library (STL)

The STL is C++‘s superpower. It provides efficient, tested, and reusable components. Rule #1 of C++: If it’s in the STL, don’t write it yourself. Why write a buggy linked list when std::list exists and is optimized by experts?

1. Containers

Containers are data structures that store collections of objects. They manage memory automatically.

Sequential Containers (Ordered)

std::vector (Dynamic Array)
  • What is it?: An array that can grow.
  • Use default: 99% of the time, use vector. It’s cache-friendly and fast.
  • Operations: Fast access ([]), fast push back. Slow insert in the middle.
#include <vector>

std::vector<int> nums = {1, 2, 3};
nums.push_back(4); // Add to end: {1, 2, 3, 4}
nums[0] = 10;      // Access by index
std::array (Fixed-Size Array)
  • What is it?: A safer version of C-style arrays (int arr[5]).
  • Use when: Size is known at compile time and won’t change.
  • Zero overhead: No dynamic allocation.
#include <array>
std::array<int, 3> point = {10, 20, 30};

Associative Containers (Key-Value / Sorted)

std::map (Ordered Map)
  • What is it?: A tree-based dictionary.
  • Order: Keys are always sorted (alphabetically or numerically).
  • Complexity: O(log n).
#include <map>

std::map<std::string, int> scores;
scores["Alice"] = 100;
scores["Bob"] = 90;

// Iterates in alphabetical order of keys: Alice, then Bob
for (const auto& [name, score] : scores) {
    std::cout << name << ": " << score << "\n";
}

Unordered Containers (Hash Tables)

std::unordered_map
  • What is it?: A hash table.
  • Order: Random.
  • Complexity: O(1) average (Very fast).
  • Use when: You need fast lookups and don’t care about order.

2. Iterators

Iterators are the glue between Containers and Algorithms. Think of them as “smart pointers” that know how to navigate a specific container.
  • begin(): Points to the first element.
  • end(): Points to one past the last element.
std::vector<int> nums = {10, 20, 30};

// Old school iterator usage
for (auto it = nums.begin(); it != nums.end(); ++it) {
    std::cout << *it << " "; // Dereference to get value
}

Range-Based For Loop

This syntactic sugar uses iterators behind the scenes but is much cleaner.
for (int x : nums) {
    std::cout << x << " ";
}

3. Algorithms

The <algorithm> header contains 100+ functions for sorting, searching, and manipulating ranges. They are often faster and less buggy than writing your own loops.

Sorting & Searching

#include <algorithm>
#include <vector>

std::vector<int> nums = {5, 1, 9, 3};

// Sort (O(n log n))
std::sort(nums.begin(), nums.end()); // {1, 3, 5, 9}

// Binary Search (Requires sorted range) - Returns true/false
bool found = std::binary_search(nums.begin(), nums.end(), 5); // true

Transformations

// Multiply every element by 2
std::for_each(nums.begin(), nums.end(), [](int& n) {
    n *= 2;
});

Finding

// Find first even number
auto it = std::find_if(nums.begin(), nums.end(), [](int n) {
    return n % 2 == 0;
});

if (it != nums.end()) {
    std::cout << "Found: " << *it;
}

4. Lambdas (Anonymous Functions)

Lambdas allow you to write small, throwaway functions inline. They are perfect for passing to algorithms like sort or find_if. Syntax: [capture](parameters) -> return_type { body }
int multiplier = 10;

// Capture 'multiplier' by value [=] so we can use it inside
auto timesTen = [multiplier](int n) {
    return n * multiplier;
};

std::cout << timesTen(5); // 50

Capture Clauses

  • []: No capture. Function is isolated.
  • [=]: Capture all local variables by value (copy).
  • [&]: Capture all local variables by reference (can modify original).

Summary

  • Containers: Use std::vector by default. Use std::map for sorted keys, std::unordered_map for speed.
  • Iterators: Abstract the navigation of data.
  • Algorithms: Prefer std::sort, std::find, etc., over writing raw loops.
  • Lambdas: Write concise, local functions for algorithms.
Next, we’ll look at the cutting edge: Modern C++ (C++11 to C++20) features.