CodeRigor

FREE COURSE / REAL PRACTICE

C++ language fundamentals

Understand copying, references, const, RAII, classes, templates and the language rules behind dependable C++ interfaces.

Free lessons & exercises40 authored lessons17 units

What you’ll work toward

Choose ownership deliberately, express constraints and build small C++ interfaces you can test.

Read an explanation, inspect the diagrams and work through the available checks, debugging exercises and builds. Feedback and prerequisite links guide the next step.

Before you start

The entry lesson has no earlier CodeRigor skill prerequisite. Start there and follow the sequence.

Individual lessons can add prerequisites. The course map shows your actual readiness.

A look inside the first lesson

Values, references and const

C++
#include <print>
#include <string>

int main() {
    std::string a = "hello";
    std::string b = a;      // b is a copy
    b += ", world";
    std::println("a = {}, b = {}", a, b);   // a is unchanged
}

Your course outline

Follow the lessons in curriculum order. Open a unit to preview the ideas you’ll work with.

UNIT 013 lessons Foundations
  1. LESSON 01.01

    Values, references and const

    Choose deliberately between copying, aliasing and pointing; write const-correct APIs; never let a reference outlive its object.

    Open lesson
  2. LESSON 01.02

    std::vector, std::span and std::string_view

    Own sequences with std::vector, pass them around with std::span and std::string_view, and never let a view outlive what it looks at.

    Open lesson
  3. LESSON 01.03

    RAII, scope and object lifetime

    Tie every resource to an object's lifetime so cleanup happens exactly once — on normal exit, early return and exceptions.

    Open lesson
UNIT 022 lessons Owning things
  1. LESSON 02.01

    Classes: invariants and the rule of zero/five

    Design classes that establish and keep an invariant, let the compiler write the special members (rule of zero), and know exactly when it can't.

    Open lesson
  2. LESSON 02.02

    Move semantics and value categories

    Know which expressions can be moved from, write correct noexcept move operations, and know when the compiler elides copies for you.

    Open lesson
UNIT 033 lessons Generic code
  1. LESSON 03.01

    Templates and concepts

    Write generic code that says what it needs: templates, deduction, concepts and requires-clauses, folds, and C++26 pack indexing.

    Open lesson
  2. LESSON 03.02

    Iterators and ranges basics

    Know what each iterator category promises, make your own container work with std::ranges, and use sentinels, projections and simple views.

    Open lesson
  3. LESSON 03.03

    Errors as values: optional and expected

    Return "maybe a value" and "a value or an error" as types, chain them without nested ifs, and know when an exception is the better tool.

    Open lesson
UNIT 042 lessons Hashing and heaps
  1. LESSON 04.01

    Smart pointers and ownership

    Decide who owns what — unique, shared or borrowed — and express it with unique_ptr, shared_ptr, weak_ptr and plain references, without leaks, cycles or double frees.

    Open lesson
  2. LESSON 04.02

    Lambdas and callables

    Write lambdas with deliberate captures, and pick the right callable type for an API: a template, std::function_ref, std::function or std::move_only_function.

    Open lesson
UNIT 053 lessons Compile time and trees
  1. LESSON 05.01

    Compile-time programming

    Move work to compile time with constexpr, consteval and constinit — and let the compiler reject undefined behaviour for you.

    Open lesson
  2. LESSON 05.02

    std::format and std::print

    Type-safe, compile-time-checked formatting: the replacement-field grammar, ranges, allocation-free output, runtime patterns, and custom formatters.

    Open lesson
  3. LESSON 05.03

    Flat containers: flat_map and inplace_vector

    Sorted-vector maps for read-mostly data, and fixed-capacity vectors that never allocate — when they beat node-based and heap-based containers, and what they cost.

    Open lesson
UNIT 062 lessons Sum types, contracts, graphs
  1. LESSON 06.01

    Sum types and value-semantic polymorphism

    Model closed sets of alternatives with std::variant and exhaustive visitors, build recursive value types with std::indirect, and get copyable open hierarchies with std::polymorphic instead of unique_ptr plus clone().

    Open lesson
  2. LESSON 06.02

    Contracts (C++26)

    State what callers must ensure and what a function promises with pre, post and contract_assert — and know exactly what happens when they're broken.

    Open lesson
UNIT 071 lesson Pipelines and memory
  1. LESSON 07.01

    Ranges: views and pipelines

    Compose lazy views with |, materialise with ranges::to, fold, generate with std::generator, and know where views dangle or cache.

    Open lesson
UNIT 082 lessons Reflection and advanced structures
  1. LESSON 08.01

    Static reflection (C++26)

    Inspect types, members and enumerators at compile time with ^^ and std::meta, splice them back with [: :], and generate to_string, equality and hashing instead of writing them by hand.

    Open lesson
  2. LESSON 08.02

    Modern pack tricks: indexing, binding packs and friends

    Index packs directly with Ts...[I], destructure tuples and aggregates into packs with auto [...xs], and use structured bindings as conditions and _ placeholders — the C++26 features that retire most index_sequence boilerplate.

    Open lesson
UNIT 093 lessons Standard containers: contracts, bits & duplicate keys
  1. LESSON 09.01

    Standard containers: identity, transfer & invalidation

    Apply list splice, forward_list erasure, map node handles and borrowed array views; choose storage by ownership and stability guarantees.

    Open lesson
  2. LESSON 09.02

    Packed booleans: vector<bool>, proxies & bitset

    Distinguish bit proxies from boolean values, use fixed-width bit operations beyond 64 bits, and preserve snapshots, bounds and subset-sum semantics.

    Open lesson
  3. LESSON 09.03

    Duplicate keys: ordered, hashed & flat containers

    Use multimap/multiset and unordered multi variants, plus flat_set/flat_multiset/flat_multimap; preserve multiplicity, deterministic results and sorted invariants.

    Open lesson
UNIT 102 lessons Shaped views & stable block storage
  1. LESSON 10.01

    mdspan: shape, strides & borrowed multidimensional data

    Use actual C++23 mdspan with right, left and padded layouts; validate backing spans and overflow, distinguish logical size from storage, and transpose safely.

    Open lesson
  2. LESSON 10.02

    hive storage: stable entities with the reference implementation

    Practice stable insertion and erasure using pinned plf::hive, with a consistent id index and lifetime checks. Native std::hive remains unavailable here.

    Open lesson
UNIT 113 lessons C library: bytes, strings & characters
  1. LESSON 11.01

    Byte buffers & memory functions

    Validate byte ranges before calling memmove; distinguish overlap, byte counts and object representation from typed value operations.

    Open lesson
  2. LESSON 11.02

    C strings, terminators & bounded adapters

    Keep byte length, buffer capacity and NUL termination distinct; use memchr to inspect bounded storage and copy text without silent truncation.

    Open lesson
  3. LESSON 11.03

    Character classification, locale & byte text

    Use cctype with unsigned-byte values, trim C-locale whitespace, and separate byte-oriented case conversion from Unicode text processing.

    Open lesson
UNIT 123 lessons C library: conversion, allocation & streams
  1. LESSON 12.01

    Checked numeric conversion & errno

    Combine strtol/strtod, end pointers, errno and destination bounds; reject incomplete tokens, embedded NUL, whitespace, overflow and nonfinite numbers.

    Open lesson
  2. LESSON 12.02

    malloc, calloc, realloc & ownership

    Own C-allocated byte storage, check size products before allocation, preserve the old block on realloc failure and release with the matching allocator.

    Open lesson
  3. LESSON 12.03

    FILE streams, buffering & binary I/O

    Use fread/fwrite counts, distinguish EOF from stream errors, and flush buffered output while keeping FILE ownership explicit.

    Open lesson
UNIT 133 lessons C library: formatting, callbacks & time
  1. LESSON 13.01

    Format strings, snprintf & bounded input

    Match variadic format arguments exactly, interpret snprintf counts and truncation, and separate trusted formats from input data.

    Open lesson
  2. LESSON 13.02

    qsort, bsearch & C callbacks

    Sort trivially copyable records with an overflow-safe C comparator, then search by key without assuming stable order or a particular duplicate match.

    Open lesson
  3. LESSON 13.03

    Calendar time, CPU clocks & formatting

    Distinguish time_t, tm and clock_t; format validated calendar fields and convert CPU ticks without assuming a Unix epoch or wall-clock timing.

    Open lesson
UNIT 142 lessons Core Guidelines: interfaces, expressions & enums
  1. LESSON 14.01

    Core Guidelines: explicit, bounded interfaces

    Design APIs that carry argument roles, bounds, ownership and failure policy; validate borrowed input before returning owned domain values.

    Open lesson
  2. LESSON 14.02

    Core Guidelines: checked expressions and scoped enums

    Initialize before use, validate arithmetic and conversions before evaluation, and represent enum domains with explicit checked boundaries.

    Open lesson
UNIT 152 lessons Core Guidelines: class design & exception guarantees
  1. LESSON 15.01

    Core Guidelines: polymorphic interfaces without slicing

    Choose value types or abstract interfaces deliberately; prevent slicing, preserve dynamic types through clone, and copy owned operations safely.

    Open lesson
  2. LESSON 15.02

    Core Guidelines: exception guarantees and commit points

    State the basic, strong and no-throw guarantees; stage fallible work under RAII and commit without changing promised state on failure.

    Open lesson
UNIT 162 lessons Binary & hex
  1. LESSON 16.01

    Binary: bits, place values & unsigned words

    Convert binary and decimal, distinguish a value from its spelling, and validate fixed-width unsigned words without overflowing or shifting by the type width.

    Open lesson
  2. LESSON 16.02

    Hexadecimal: nibbles, bytes & byte order

    Read and write hex bytes, convert four-bit groups, and decode explicit little- and big-endian values without confusing display order with memory order.

    Open lesson
UNIT 172 lessons Signed encodings
  1. LESSON 17.01

    One's complement: negative zero & end-around carry

    Model one's-complement signed words explicitly: encode negatives by inverting within the width, preserve both zeros, and add with end-around carry.

    Open lesson
  2. LESSON 17.02

    Two's complement: signed values, extension & overflow

    Encode and decode two's-complement words, sign-extend them, and distinguish unsigned carry from signed overflow without executing C++ signed overflow.

    Open lesson