Standard Library Overview

This section documents C++23 (ISO/IEC 14882:2024), as published by ISO/IEC JTC1/SC22/WG21 (wg21), verified against the freely available working draft N5046 (eel.is/c++draft) and cppreference.com.

This content was generated with the assistance of AI and should be verified against the working draft and cppreference.com before being relied on in production.

This section’s bibliography lists the reference material consulted while preparing these pages.

How the Library Is Organized

The standard library is organized by area rather than by one monolithic header; the pages in this section mirror that layout roughly one-to-one:

Area Representative headers

Containers

<vector>, <array>, <map>, <unordered_map>, <flat_map>

Iterators & algorithms

<iterator>, <algorithm>, <numeric>, <ranges>

Strings & text

<string>, <string_view>, <charconv>, <format>, <regex>

Vocabulary types

<optional>, <variant>, <any>, <expected>, <tuple>, <utility>

Numerics

<cmath>, <numbers>, <random>, <complex>, <bit>

I/O

<iostream>, <fstream>, <sstream>, <print>, <filesystem>

Time

<chrono>

Concurrency

<thread>, <mutex>, <atomic>, <future>, <coroutine>

Memory

<memory>, <memory_resource>, <new>

Error handling

<exception>, <stdexcept>, <system_error>, <stacktrace>

Metaprogramming

<type_traits>, <concepts>, <version>

The std Namespace

Every standard-library name lives in namespace std (or a nested namespace like std::chrono, std::filesystem, std::ranges) — see Namespaces, Modules, and the Preprocessor for why using namespace std; at global/header scope is best avoided.

C Compatibility Headers

C++ wraps most of the C standard library, offering it under two names: the <c*.h> C-style name (global namespace) and the <c*> C++-style name (std:: namespace, and often also injected into the global namespace as an implementation-defined extension):

#include <cmath>       // preferred: std::sqrt, std::pow, ...
#include <math.h>       // legacy C header: sqrt, pow, ... in the global namespace

#include <cstdlib>      // preferred: std::malloc, std::exit, ...
#include <cstring>       // preferred: std::memcpy, std::strlen, ...

Prefer the <c*> forms in new C++ code — they guarantee the names are in std::, avoiding accidental global namespace pollution.

Freestanding vs. Hosted

A hosted implementation (what runs on a desktop/server OS) provides the entire standard library. A freestanding implementation (embedded targets, kernels, some game-console SDKs) is only required to provide a minimal subset — core language support (<type_traits>, <concepts>, parts of <utility>/<atomic>), but not, in general, containers, iostreams, or exceptions-dependent facilities. C++23 formalized and grew exactly which library parts freestanding implementations must supply (std::vector, std::string_view, and several algorithms newly became freestanding-required).

std::size, std::data, and std::ssize

Free functions (C++17/20, <iterator>) that work uniformly across C arrays, containers, and std::initializer_list, instead of a member call that arrays don’t have:

#include <iterator>
#include <vector>
#include <cassert>

int main() {
    int arr[5] = {1, 2, 3, 4, 5};
    std::vector<int> v = {1, 2, 3};

    assert(std::size(arr) == 5);              // works on a raw array -- arr.size() would not compile
    assert(std::size(v) == 3);                 // works on any container with .size()
    assert(std::data(v) == &v[0]);              // pointer to the first element
    assert(std::ssize(v) == 3);                  // C++20: signed size, avoiding signed/unsigned comparison bugs
                                                   // (see std::cmp_less in Operators and Expressions)
    return 0;
}

std::hash and Hashing Custom Types

Unordered containers (std::unordered_map/std::unordered_set, see Containers) need a std::hash<Key> specialization for any custom key type:

#include <unordered_map>
#include <string>
#include <functional>

struct Point {
    int x, y;
    bool operator==(const Point&) const = default;
};

template <>
struct std::hash<Point> {
    std::size_t operator()(const Point& p) const noexcept {
        return std::hash<int>{}(p.x) ^ (std::hash<int>{}(p.y) << 1);   // a simple, illustrative combiner --
    }                                                                    // prefer boost::hash_combine or a
};                                                                        // well-reviewed combiner in production

int main() {
    std::unordered_map<Point, std::string> labels;
    labels[Point{0, 0}] = "origin";
    return 0;
}

std::exit and std::atexit

#include <cstdlib>
#include <cstdio>

void cleanup() { std::puts("cleaning up"); }

int main() {
    std::atexit(cleanup);       // registered cleanup functions run, in reverse order, on normal termination
    if (false) {
        std::exit(EXIT_FAILURE);   // terminates immediately -- runs atexit handlers, but NOT local destructors
    }                                // on the current call stack (unlike a normal "return" from main)
    return 0;
}

std::exit skips stack unwinding entirely — prefer throwing an exception or returning an error and letting main return normally whenever local destructors (RAII cleanup) must run.

See Also