Boring C++
Chrono (
Filesystem (
Type Traits (
Numeric Limits (
Standard Library Cheat Sheet
5 min read
Appendix B: Standard Library Cheat Sheet
A quick reference for the standard library headers and functions used in this book.
Headers by Topic
| Header | What it provides |
|---|---|
<iostream> |
std::cin, std::cout, std::cerr |
<string> |
std::string |
<string_view> |
std::string_view (C++17) |
<format> |
std::format (C++20) |
<vector> |
std::vector |
<array> |
std::array |
<map> |
std::map, std::multimap |
<unordered_map> |
std::unordered_map |
<set> |
std::set, std::multiset |
<unordered_set> |
std::unordered_set |
<span> |
std::span (C++20) |
<algorithm> |
std::sort, std::find, etc. |
<numeric> |
std::accumulate, std::iota, etc. |
<ranges> |
std::views::filter, etc. (C++20) |
<memory> |
std::unique_ptr, std::shared_ptr |
<optional> |
std::optional (C++17) |
<expected> |
std::expected (C++23) |
<variant> |
std::variant (C++17) |
<functional> |
std::function, std::bind |
<stdexcept> |
std::runtime_error, etc. |
<exception> |
std::exception |
<thread> |
std::thread, std::jthread |
<mutex> |
std::mutex, std::lock_guard |
<condition_variable> |
std::condition_variable |
<atomic> |
std::atomic |
<future> |
std::future, std::async |
<chrono> |
std::chrono::steady_clock, durations |
<fstream> |
std::ifstream, std::ofstream |
<sstream> |
std::ostringstream, std::istringstream |
<filesystem> |
std::filesystem::path, etc. (C++17) |
<cstdint> |
int32_t, uint64_t, etc. |
<cmath> |
std::sqrt, std::abs, etc. |
<cassert> |
assert |
<limits> |
std::numeric_limits<T> |
<type_traits> |
std::is_integral_v<T>, etc. |
<concepts> |
std::integral, std::floating_point, etc. (C++20) |
std::vector
std::vector<T> v; // empty
std::vector<T> v(n, val); // n copies of val
std::vector<T> v{a, b, c}; // initializer list
v.push_back(x); // append copy
v.emplace_back(args); // construct in place
v.pop_back(); // remove last
v.insert(it, x); // insert before it (O(n))
v.erase(it); // remove at it (O(n))
v.erase(it1, it2); // remove range [it1, it2)
v.clear(); // remove all
v.resize(n); // resize to n
v.reserve(n); // allocate capacity for n
v[i] // access, no bounds check
v.at(i) // access, throws if out of range
v.front() // first element
v.back() // last element
v.size() // number of elements
v.empty() // true if empty
v.capacity() // allocated capacity
v.begin() / v.end() // iterators
v.rbegin() / v.rend() // reverse iterators
std::map / std::unordered_map
std::map<K, V> m;
std::unordered_map<K, V> um;
m[key] = val; // insert or overwrite (creates entry if absent!)
m.insert({key, val}); // insert (fails if key exists)
m.at(key); // access, throws if not found
m.find(key); // returns iterator, or end() if not found
m.count(key); // 0 or 1 (for map)
m.contains(key); // C++20: true/false
m.erase(key); // remove by key
m.erase(it); // remove by iterator
m.size();
m.empty();
m.clear();
// Safe access pattern (does NOT insert):
if (auto it = m.find(key); it != m.end()) {
use(it->second);
}
std::string
std::string s{"hello"};
std::string s(n, 'x'); // n copies of character 'x'
s.size() / s.length() // number of characters
s.empty()
s.clear()
s += " world"; // append
s + t // concatenate (new string)
s[i] // character at i, no bounds check
s.at(i) // character at i, bounds checked
s.front() / s.back()
s.substr(pos, len) // substring
s.find(substr) // pos of substr, or std::string::npos
s.rfind(substr) // last occurrence
s.starts_with(prefix) // C++20
s.ends_with(suffix) // C++20
s.contains(substr) // C++20
s.replace(pos, len, newstr) // in-place replacement
// Conversion
std::stoi(s) std::stol(s) std::stod(s) // string to number
std::to_string(n) // number to string
std::optional
std::optional<T> opt; // empty
std::optional<T> opt{value}; // has value
std::nullopt // empty sentinel
opt.has_value() // or: if (opt)
*opt // dereference (undefined if empty)
opt.value() // dereference (throws std::bad_optional_access if empty)
opt.value_or(def) // value, or def if empty
opt.reset() // make empty
opt.emplace(args) // construct in place
std::expected (C++23)
std::expected<T, E> result{value}; // success
std::expected<T, E> err{std::unexpected{e}}; // failure
result.has_value() // or: if (result)
*result // access value (UB if has error)
result.value() // access value (throws std::bad_expected_access if error)
result.error() // access error (UB if has value)
result.value_or(d) // value or default
Common Algorithms
// Sort
std::sort(first, last);
std::sort(first, last, cmp);
std::stable_sort(first, last);
std::ranges::sort(container); // C++20
// Search
std::find(first, last, val); // returns iterator
std::find_if(first, last, pred);
std::binary_search(first, last, val); // requires sorted; returns bool
std::lower_bound(first, last, val); // first element >= val
std::upper_bound(first, last, val); // first element > val
// Counting
std::count(first, last, val);
std::count_if(first, last, pred);
// Transforming
std::transform(in_first, in_last, out_first, fn);
std::for_each(first, last, fn);
std::copy(first, last, out_first);
std::fill(first, last, val);
// Removing (use with erase!)
auto newEnd = std::remove(first, last, val);
auto newEnd = std::remove_if(first, last, pred);
container.erase(newEnd, container.end());
// Predicates
std::all_of(first, last, pred);
std::any_of(first, last, pred);
std::none_of(first, last, pred);
// Min/Max
std::min(a, b) / std::max(a, b)
std::min_element(first, last);
std::max_element(first, last);
std::clamp(val, lo, hi);
// Numeric (<numeric>)
std::accumulate(first, last, init);
std::accumulate(first, last, init, binOp);
std::iota(first, last, startVal); // fill with increasing values
std::partial_sum(first, last, out);
// Unique (requires sorted; use with erase)
auto newEnd = std::unique(first, last);
container.erase(newEnd, container.end());
// Partition
auto mid = std::partition(first, last, pred);
Ranges (C++20)
// Views (lazy, composable)
data | std::views::filter(pred)
data | std::views::transform(fn)
data | std::views::take(n)
data | std::views::drop(n)
data | std::views::reverse
data | std::views::enumerate // C++23: (index, value) pairs
// Range algorithms (no begin/end needed)
std::ranges::sort(container);
std::ranges::find(container, val);
std::ranges::count_if(container, pred);
std::ranges::transform(container, out, fn);
std::ranges::copy(container, out);
Chrono (<chrono>)
using namespace std::chrono;
auto start = steady_clock::now();
// ... do work ...
auto end = steady_clock::now();
auto ms = duration_cast<milliseconds>(end - start).count();
auto us = duration_cast<microseconds>(end - start).count();
// Sleep
std::this_thread::sleep_for(milliseconds{100});
std::this_thread::sleep_for(seconds{1});
Filesystem (<filesystem>, C++17)
namespace fs = std::filesystem;
fs::path p{"dir/file.txt"};
p.filename() // "file.txt"
p.stem() // "file"
p.extension() // ".txt"
p.parent_path() // "dir"
p / "subdir" // "dir/subdir"
fs::exists(p)
fs::is_regular_file(p)
fs::is_directory(p)
fs::file_size(p)
fs::create_directory(p)
fs::create_directories(p) // creates all parent dirs too
fs::remove(p)
fs::copy(from, to)
for (const auto& entry : fs::directory_iterator(p)) {
std::cout << entry.path() << "\n";
}
Type Traits (<type_traits>)
std::is_integral_v<T>
std::is_floating_point_v<T>
std::is_pointer_v<T>
std::is_same_v<T, U>
std::is_base_of_v<Base, Derived>
std::is_constructible_v<T, Args...>
std::is_copy_constructible_v<T>
std::is_move_constructible_v<T>
std::remove_reference_t<T>
std::decay_t<T>
std::enable_if_t<cond, T> // pre-Concepts SFINAE
Numeric Limits (<limits>)
std::numeric_limits<int>::max() // 2147483647
std::numeric_limits<int>::min() // -2147483648
std::numeric_limits<double>::max() // ~1.8e308
std::numeric_limits<double>::epsilon() // ~2.2e-16
std::numeric_limits<double>::infinity()
std::numeric_limits<double>::quiet_NaN()