C++ Cheatsheet

STL Algorithms

Use this C++ reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.

Header and Iterator Requirements

#include <algorithm>    // most algorithms
#include <numeric>      // numeric algorithms (iota, accumulate, etc.)
#include <execution>    // execution policies (C++17)

Most algorithms operate on half-open ranges [first, last) of iterators. The range library (C++20) provides std::ranges:: versions that accept containers directly and support composable views.

Non-Modifying Sequence Algorithms

#include <algorithm>
std::vector<int> v = {3, 1, 4, 1, 5, 9, 2, 6};

// Search
std::find(v.begin(), v.end(), 4);               // iterator to first 4, or end
std::find_if(v.begin(), v.end(), [](int x){ return x > 5; });
std::find_if_not(v.begin(), v.end(), [](int x){ return x < 5; });
std::find_first_of(v.begin(), v.end(), s.begin(), s.end()); // any of set
std::adjacent_find(v.begin(), v.end());         // first consecutive equal pair
std::search(v.begin(), v.end(), sub.begin(), sub.end()); // subsequence
std::search_n(v.begin(), v.end(), 2, 1);        // 2 consecutive 1s

// Count
std::count(v.begin(), v.end(), 1);              // 2
std::count_if(v.begin(), v.end(), [](int x){ return x % 2 == 0; });

// Test conditions
std::all_of(v.begin(), v.end(), [](int x){ return x > 0; });   // true
std::any_of(v.begin(), v.end(), [](int x){ return x > 8; });   // true
std::none_of(v.begin(), v.end(), [](int x){ return x < 0; });  // true

// Iterate
std::for_each(v.begin(), v.end(), [](int& x){ x *= 2; });
std::for_each_n(v.begin(), 3, [](int& x){ ++x; });  // first 3 elements

// Mismatch / equal
std::mismatch(v.begin(), v.end(), w.begin());   // pair of iterators
std::equal(v.begin(), v.end(), w.begin());       // true if ranges match
std::equal(v.begin(), v.end(), w.begin(), w.end()); // both ranges

// Min/max element
std::min_element(v.begin(), v.end());            // iterator to minimum
std::max_element(v.begin(), v.end());            // iterator to maximum
std::minmax_element(v.begin(), v.end());         // pair of iterators

Modifying Sequence Algorithms

std::vector<int> v = {1, 2, 3, 4, 5};
std::vector<int> out(5);

// Copy
std::copy(v.begin(), v.end(), out.begin());
std::copy_if(v.begin(), v.end(), out.begin(), [](int x){ return x % 2 == 0; });
std::copy_n(v.begin(), 3, out.begin());
std::copy_backward(v.begin(), v.end(), out.end());

// Move
std::move(v.begin(), v.end(), out.begin());      // move-assign each element
std::move_backward(v.begin(), v.end(), out.end());

// Transform
std::transform(v.begin(), v.end(), out.begin(), [](int x){ return x * x; });
// Binary transform (two input ranges)
std::transform(v.begin(), v.end(), w.begin(), out.begin(),
               [](int a, int b){ return a + b; });

// Fill
std::fill(v.begin(), v.end(), 0);               // fill with value
std::fill_n(v.begin(), 3, 99);                  // fill first 3
std::generate(v.begin(), v.end(), [n=0]() mutable { return n++; });
std::generate_n(v.begin(), 3, rand);

// Replace
std::replace(v.begin(), v.end(), 1, 99);        // replace 1 → 99
std::replace_if(v.begin(), v.end(), [](int x){ return x < 3; }, 0);
std::replace_copy(v.begin(), v.end(), out.begin(), 1, 99);  // copy+replace

// Remove (erases logically — returns new "end"; use with v.erase())
auto new_end = std::remove(v.begin(), v.end(), 3);
v.erase(new_end, v.end());         // erase-remove idiom
std::remove_if(v.begin(), v.end(), [](int x){ return x % 2 == 0; });
std::remove_copy(v.begin(), v.end(), out.begin(), 3);  // copy without 3

// Unique (removes consecutive duplicates; sort first for global unique)
std::sort(v.begin(), v.end());
v.erase(std::unique(v.begin(), v.end()), v.end());

// Reverse
std::reverse(v.begin(), v.end());
std::reverse_copy(v.begin(), v.end(), out.begin());

// Rotate
std::rotate(v.begin(), v.begin() + 2, v.end()); // make v[2] the new first
std::rotate_copy(v.begin(), v.begin() + 2, v.end(), out.begin());

// Shuffle
#include <random>
std::mt19937 rng(std::random_device{}());
std::shuffle(v.begin(), v.end(), rng);

// Sample (C++17)
std::sample(v.begin(), v.end(), out.begin(), 3, rng);  // 3 random elements

Binary Search (on sorted ranges)

// v must be sorted!
std::binary_search(v.begin(), v.end(), 4);      // bool: is 4 in v?
std::lower_bound(v.begin(), v.end(), 4);         // first >= 4
std::upper_bound(v.begin(), v.end(), 4);         // first >  4
std::equal_range(v.begin(), v.end(), 4);         // pair(lower, upper)

// With custom comparator
std::lower_bound(v.begin(), v.end(), 4, std::greater<>{});  // sorted descending

Numeric Algorithms (<numeric>)

#include <numeric>

std::vector<int> v = {1, 2, 3, 4, 5};

std::accumulate(v.begin(), v.end(), 0);                    // sum: 15
std::accumulate(v.begin(), v.end(), 1, std::multiplies<>{});  // product: 120

std::reduce(v.begin(), v.end());                           // sum (C++17, parallel-able)
std::reduce(v.begin(), v.end(), 0, std::plus<>{});

std::transform_reduce(v.begin(), v.end(), 0, std::plus<>{},
                      [](int x){ return x * x; });         // sum of squares (C++17)

std::inner_product(v.begin(), v.end(), w.begin(), 0);      // dot product

std::partial_sum(v.begin(), v.end(), out.begin());         // prefix sums
std::exclusive_scan(v.begin(), v.end(), out.begin(), 0);   // exclusive prefix sum (C++17)
std::inclusive_scan(v.begin(), v.end(), out.begin());       // inclusive (C++17)

std::adjacent_difference(v.begin(), v.end(), out.begin()); // differences
std::iota(v.begin(), v.end(), 0);                          // 0, 1, 2, 3, 4
std::gcd(12, 8);   // 4  (C++17)
std::lcm(4, 6);    // 12 (C++17)
std::midpoint(4, 8); // 6 (C++20, no overflow)

Set Operations (on sorted ranges)

std::vector<int> a = {1, 2, 3, 4}, b = {3, 4, 5, 6};
std::vector<int> out;

std::set_union(a.begin(), a.end(), b.begin(), b.end(), back_inserter(out));
// {1,2,3,4,5,6}
std::set_intersection(a.begin(), a.end(), b.begin(), b.end(), back_inserter(out));
// {3,4}
std::set_difference(a.begin(), a.end(), b.begin(), b.end(), back_inserter(out));
// {1,2}
std::set_symmetric_difference(a.begin(), a.end(), b.begin(), b.end(), back_inserter(out));
// {1,2,5,6}

std::includes(a.begin(), a.end(), sub.begin(), sub.end()); // true if sub ⊆ a
std::merge(a.begin(), a.end(), b.begin(), b.end(), back_inserter(out)); // sorted merge
std::inplace_merge(v.begin(), v.begin() + n, v.end());  // merge two halves in-place

Heap Operations

std::vector<int> v = {3, 1, 4, 1, 5};
std::make_heap(v.begin(), v.end());   // O(n), max at front
v.front();                            // max element
std::push_heap(v.begin(), v.end());   // after push_back, restore heap property
std::pop_heap(v.begin(), v.end());    // move max to back; then pop_back()
v.pop_back();
std::sort_heap(v.begin(), v.end());   // heap sort (destroys heap property)
std::is_heap(v.begin(), v.end());
std::is_heap_until(v.begin(), v.end());

Permutation Algorithms

std::vector<int> v = {1, 2, 3};
std::next_permutation(v.begin(), v.end());  // advances to next; returns false if wrapped
std::prev_permutation(v.begin(), v.end());
std::is_permutation(v.begin(), v.end(), w.begin()); // true if same elements

// Iterate all permutations
std::sort(v.begin(), v.end());
do {
    // process v
} while (std::next_permutation(v.begin(), v.end()));

Execution Policies (C++17, <execution>)

#include <execution>

std::sort(std::execution::par, v.begin(), v.end());         // parallel
std::sort(std::execution::seq, v.begin(), v.end());         // sequential (default)
std::sort(std::execution::par_unseq, v.begin(), v.end());   // parallel + vectorized
std::reduce(std::execution::par, v.begin(), v.end());       // parallel reduce

// Note: may require linking -ltbb (Intel TBB) on some platforms

C++20 Ranges

#include <ranges>

std::vector<int> v = {1, 2, 3, 4, 5, 6};

// Range algorithms (take container, no begin/end needed)
std::ranges::sort(v);
std::ranges::reverse(v);
std::ranges::find(v, 3);
std::ranges::count_if(v, [](int x){ return x % 2 == 0; });
std::ranges::copy(v, std::back_inserter(out));

// Views — lazy, composable, zero-copy transformations
using namespace std::views;

auto evens  = v | filter([](int x){ return x % 2 == 0; });
auto doubled = v | transform([](int x){ return x * 2; });
auto taken  = v | take(3);
auto dropped = v | drop(2);
auto rev    = v | reverse;
auto mapKeys = myMap | keys;     // map keys
auto mapVals = myMap | values;   // map values

// Compose
auto pipeline = v | filter([](int x){ return x > 2; })
                  | transform([](int x){ return x * x; })
                  | take(3);

for (int x : pipeline) { std::cout << x << " "; }  // lazy evaluation

// Materialize into a vector (C++23)
// auto vec = pipeline | std::ranges::to<std::vector>();

// Other views
iota(1, 10);              // {1, 2, ..., 9}
repeat(42);               // infinite: 42, 42, 42, ...
repeat(42, 5);            // {42, 42, 42, 42, 42} (C++23)
std::views::zip(a, b);    // pairs (C++23)
std::views::enumerate(v); // (index, value) pairs (C++23)
std::views::split(str, ' '); // split by delimiter
std::views::join(ranges);    // flatten
std::views::common(r);       // make begin/end same type (for old algorithms)

Iterator Adaptors and Utilities

#include <iterator>

// Output iterators
std::back_insert_iterator<std::vector<int>> bi(v);    // back_inserter(v)
std::front_insert_iterator<std::list<int>> fi(lst);   // front_inserter(lst)
std::insert_iterator<std::set<int>> ii(s, s.begin()); // inserter(s, pos)

// Usage
std::copy(src.begin(), src.end(), std::back_inserter(dest));

// Stream iterators
std::istream_iterator<int> in(std::cin), eof;
std::copy(in, eof, std::back_inserter(v));    // read all ints from stdin
std::ostream_iterator<int> out(std::cout, " ");
std::copy(v.begin(), v.end(), out);           // print all ints

// Advance and distance
std::advance(it, 5);                // move iterator by n (forward/back for bidir)
std::distance(first, last);         // number of steps between iterators
std::next(it, 2);                   // return iterator advanced by 2 (doesn't modify it)
std::prev(it, 2);                   // return iterator moved back by 2
std::iter_swap(it1, it2);           // swap elements pointed to by two iterators

Common Patterns

// Deduplicate sorted container
std::sort(v.begin(), v.end());
v.erase(std::unique(v.begin(), v.end()), v.end());

// Flatten-and-find: find index of min element
auto it = std::min_element(v.begin(), v.end());
int idx = std::distance(v.begin(), it);

// Frequency count
std::map<int, int> freq;
for (int x : v) ++freq[x];

// Partition in-place (odds first), then sort each partition
auto mid = std::partition(v.begin(), v.end(), [](int x){ return x % 2 != 0; });
std::sort(v.begin(), mid);
std::sort(mid, v.end());