FREE COURSE / REAL PRACTICE
C++ language fundamentals
Understand copying, references, const, RAII, classes, templates and the language rules behind dependable C++ interfaces.
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
#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.
Foundations
- 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 - 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 - 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
Owning things
- 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 - 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
Generic code
- 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 - 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 - 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
Hashing and heaps
- 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 - 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
Compile time and trees
- 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 - 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 - 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
Sum types, contracts, graphs
- 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 - 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
Pipelines and memory
Reflection and advanced structures
- 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 - 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
Standard containers: contracts, bits & duplicate keys
- 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 - 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 - 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
Shaped views & stable block storage
- 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 - 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
C library: bytes, strings & characters
- 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 - 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 - 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
C library: conversion, allocation & streams
- 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 - 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 - 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
C library: formatting, callbacks & time
- 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 - 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 - 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
Core Guidelines: interfaces, expressions & enums
- 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 - 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
Core Guidelines: class design & exception guarantees
- 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 - 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
Binary & hex
- 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 - 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
Signed encodings
- 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 - 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