FREE COURSE / REAL PRACTICE
C++ Core Guidelines
Apply selected C++ Core Guidelines through bounded interfaces, ownership, enum design, polymorphism and exception guarantees.
What you’ll work toward
Explain and test representative design contracts, and connect the selected rules to the broader guidelines reference.
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
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
- 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 - LESSON 07.02
Memory layout, alignment and caches
Know what your objects look like in memory: padding and member order, alignment, empty members, object representation without UB, and laying data out for the cache.
Open lesson
Concurrency
- LESSON 08.01
Threads, jthread and cooperative cancellation
Start, stop and join threads safely: jthread and stop tokens for cancellation, mutexes and condition variables without races or deadlocks, futures for results.
Open lesson - LESSON 08.02
Atomics and the C++ memory model
Share data between threads without locks: atomic operations, compare-exchange loops, and the memory orders (relaxed, acquire/release, seq_cst) that decide what other threads are guaranteed to see.
Open lesson - LESSON 08.03
std::execution: senders and receivers
Understand C++26's async model — lazy senders, receivers with three completion channels, operation states — by building a small standards-shaped implementation of just, then, when_all and sync_wait.
Open lesson - LESSON 08.04
Safe memory reclamation: hazard pointers and RCU
Free nodes of a lock-free structure safely and promptly: hazard pointers that protect what a thread is reading, and epoch-based RCU that frees an old version only after every reader that could see it has moved on.
Open lesson
Performance
- LESSON 09.01
Profiling and benchmarking
Measure before optimising: honest timing loops, the right statistic, keeping the optimiser from deleting your benchmark, and reading perf counters.
Open lesson - LESSON 09.02
Data-oriented design
Design around the data and how it's accessed: hot/cold splits, struct-of-arrays, dense storage with generational handles instead of pointers, batching by type, and branch-friendly data.
Open lesson
Microcontrollers: the bare machine
Production C++: build, test, debug, ship
- LESSON 11.01
Building real C++ projects: translation units, linking and CMake targets
How a multi-file C++ project becomes binaries: headers and the ODR, reading linker errors, static vs shared libraries, and target-based CMake — usage requirements, presets, packages and compile_commands.json.
Open lesson - LESSON 11.02
Testing a C++ project: CTest, fixtures and golden images
Test a real C++ library the way production teams do: CTest labels and fixtures, doctest, deterministic fixtures from a specified PRNG, golden images with documented tolerances, regression tests from observed failures, test seams and malformed input.
Open lesson
Unix/Linux: files, descriptors & filesystem
Standard containers: contracts, bits & duplicate keys
Shaped views & stable block storage
C library: bytes, strings & characters
- LESSON 15.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 15.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
C library: conversion, allocation & streams
- LESSON 16.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 16.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 16.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
Core Guidelines: interfaces, expressions & enums
- LESSON 18.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 18.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 19.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 19.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