{"id":51347040,"url":"https://github.com/jomkz/learn-modern-cpp","last_synced_at":"2026-07-02T12:04:04.709Z","repository":{"id":363446371,"uuid":"1263399117","full_name":"jomkz/learn-modern-cpp","owner":"jomkz","description":"A detailed, sequential learning path to take you from the fundamentals to advanced modern C++ (covering C++11 through C++23).","archived":false,"fork":false,"pushed_at":"2026-06-09T00:30:10.000Z","size":15,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-09T01:20:44.336Z","etag":null,"topics":["cpp","cpp11","cpp14","cpp17","cpp20","cpp23","learning","modern","modern-cpp"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jomkz.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-08T23:22:34.000Z","updated_at":"2026-06-09T00:30:14.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/jomkz/learn-modern-cpp","commit_stats":null,"previous_names":["jomkz/learn-modern-cpp"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/jomkz/learn-modern-cpp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jomkz%2Flearn-modern-cpp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jomkz%2Flearn-modern-cpp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jomkz%2Flearn-modern-cpp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jomkz%2Flearn-modern-cpp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jomkz","download_url":"https://codeload.github.com/jomkz/learn-modern-cpp/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jomkz%2Flearn-modern-cpp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35045929,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-02T02:00:06.368Z","response_time":173,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cpp","cpp11","cpp14","cpp17","cpp20","cpp23","learning","modern","modern-cpp"],"created_at":"2026-07-02T12:04:03.762Z","updated_at":"2026-07-02T12:04:04.682Z","avatar_url":"https://github.com/jomkz.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Learn Modern C++ Programming\n\nMastering modern C++ is a marathon, not a sprint. The language has evolved massively from its origins, moving away from manual memory management and raw pointers toward safer, highly expressive, and fiercely fast paradigms.\n\nHere is a detailed, sequential learning path to take you from the fundamentals to advanced modern C++ (covering C++11 through C++23).\n\n---\n\n## How to Use This Guide\n\nThis guide is structured for **all experience levels**:\n\n- **Complete beginners:** Follow every phase in order.\n- **Programmers new to C++** (Python, Java, Go, Rust, etc.): Skim Phase 2 quickly — focus on the C++-specific differences (pointers, `const`, UB, casts). You can move fast.\n- **C++98/03 developers:** Phases 2–4 will be largely review. Start paying close attention from Phase 5 (Templates) onward.\n\n**Estimated total time:** 6–12 months at a consistent pace of a few hours per week.\n\n**How to learn from it:** Read a section, then do the exercises before moving on. Passive reading is not enough for C++.\n\n**Reference solutions:** Worked solutions for every exercise live in the [`solutions/`](solutions/) directory, with comments explaining the *why* behind each design choice. Attempt the exercise first — then use the solutions to check your work or get unstuck.\n\n**Three sites to bookmark right now — use them throughout every phase:**\n\n- [learncpp.com](https://www.learncpp.com) — Best free tutorial; modern C++ from the start\n- [cppreference.com](https://en.cppreference.com) — Authoritative language and library reference\n- [isocpp.org](https://isocpp.org) — Official C++ foundation; Core Guidelines and FAQ\n\n---\n\n## Phase 1: Environment Setup and Tooling\n\n*Estimated time: ~1 week*\n\nBefore writing a single line of code, you need a robust modern development environment.\n\n- **Compiler:** Install a modern compiler that supports C++20/C++23. Choose GCC (Linux/Windows via WSL2 or MinGW), Clang (macOS/Linux), or MSVC (Windows).\n- **IDE/Editor:** Set up Visual Studio, CLion, or VS Code with the C++ extension pack.\n- **Build System:** Learn the absolute basics of **CMake**. It is the industry standard for building C++ projects. Do not rely solely on your IDE's hidden build mechanics.\n- **Package Manager:** Use **vcpkg** (Microsoft, widely adopted, integrates directly with CMake) or **Conan** (JFrog, mature binary management) to handle third-party library dependencies rather than installing them manually.\n- **Debugger:** Install **GDB** (Linux/Windows/WSL2) or **LLDB** (macOS/Clang). You will learn to use it hands-on in Phase 8, but install it now.\n- **Version Control:** Initialize a Git repository for your learning projects.\n\n\u003e ⚠️ **Platform Notes**\n\u003e\n\u003e | Platform | Recommended Compiler | Debugger | Profiler | Key Note |\n\u003e |---|---|---|---|---|\n\u003e | **Linux** | GCC or Clang via package manager | GDB | `perf` / Valgrind | Most C++ tooling assumes Linux. Best first environment. |\n\u003e | **macOS** | Homebrew LLVM (`brew install llvm`), **not** Apple Clang | LLDB | Instruments (Xcode) | Apple's bundled Clang lags C++23 support by years. Install Homebrew LLVM for full standard coverage. |\n\u003e | **Windows** | MSVC (Visual Studio) or **WSL2** for Linux toolchain | VS Debugger or GDB inside WSL2 | Visual Studio Profiler / vcperf+WPA | WSL2 is recommended for access to Linux-native tools (`perf`, Valgrind, GDB). Valgrind does **not** run natively on Windows or macOS. |\n\u003e\n\u003e For cross-platform code, use `#ifdef _WIN32`, `#ifdef __APPLE__`, and `#ifdef __linux__` to conditionally compile platform-specific sections. This is covered in depth in Phase 2.\n\n\u003e **Resources**\n\u003e - [learncpp.com — Chapter 0: Getting Started](https://www.learncpp.com/cpp-tutorial/introduction-to-these-tutorials/)\n\u003e - [CMake Official Tutorial](https://cmake.org/cmake/help/latest/guide/tutorial/index.html)\n\u003e - [vcpkg Quickstart](https://vcpkg.io/en/getting-started.html)\n\u003e - [Conan Getting Started Guide](https://docs.conan.io/2/tutorial/consuming_packages/build_simple_cmake_project.html)\n\n### Exercises\n\n1. Write a `hello_world` program and compile it manually from the command line with `g++ -std=c++20 hello.cpp -o hello`. Inspect the binary with `file hello`.\n2. Create a two-file project (a `.h` header and a `.cpp` source file) and build it with a `CMakeLists.txt` using `add_executable`.\n3. Add the `Catch2` testing library to your CMake project using vcpkg and write one passing test.\n\n---\n\n## Phase 2: C++ Foundations\n\n*Estimated time: ~3–4 weeks*\n\n⏩ *Experienced programmers: skim quickly — focus on `std::string`, `const` correctness, the C++ cast operators, the compilation pipeline, and the UB callout. These are the sharpest differences from other languages.*\n\nFocus on the core mechanics of the language before touching object-oriented concepts or modern features.\n\n- **Syntax and Structure:** Understand `#include`, the `main()` function, and basic compilation.\n- **Data Types and Variables:** Learn about integers, floating-point numbers, booleans, and characters. Understand signed vs. unsigned types and their pitfalls.\n- **`std::string`:** The fundamental string type. Learn key methods: `find`, `substr`, `replace`, `+` concatenation, `size()`, and `c_str()`. Preview `std::string_view` (C++17) — a zero-copy, non-owning view into a string for read-only operations.\n- **Control Flow:** Master `if/else` statements, `switch` cases, `for` loops, and `while` loops.\n- **Functions:** Understand function declaration, definition, parameters, return types, and function overloading.\n- **Compilation Pipeline:** Understand the four stages — *preprocessing*, *compilation*, *assembly*, and *linking*. Learn what header guards (`#ifndef/#define/#endif`) and `#pragma once` do, how **forward declarations** reduce compilation dependencies and break circular includes, and what the **One Definition Rule (ODR)** requires. This knowledge is what lets you diagnose linker errors.\n- **Namespaces:** Understand `namespace`, `using` declarations, anonymous namespaces (internal linkage), and `inline namespace`. Always qualify names explicitly (e.g., `std::cout` rather than `using namespace std;` in headers).\n- **`enum class`:** C++11 scoped enumerations. Prefer `enum class` over plain `enum` — no implicit integer conversions and no name pollution into the enclosing scope.\n- **`const` Correctness:** Apply `const` to variables, function parameters, pointers (`const int*` vs. `int* const`), and member functions (`void foo() const`). Treat `const` as a design tool — it communicates intent and prevents bugs.\n- **C++ Cast Operators:** Use `static_cast\u003cT\u003e()`, `dynamic_cast\u003cT*\u003e()`, `const_cast\u003cT\u003e()`, and `reinterpret_cast\u003cT\u003e()` instead of C-style `(int)x` casts. C-style casts silently combine all four C++ casts and bypass type safety; the C++ operators make intent explicit and catch many misuses at compile time.\n- **Pointers and References:** This is the most critical hurdle. Learn memory addresses, pointer dereferencing, passing by value versus passing by reference, and the stack versus the heap.\n- **I/O Basics:** Use `std::cin`/`std::cout` from `\u003ciostream\u003e`, `std::fstream` for files, and `std::stringstream` for string streams.\n\n\u003e ⚠️ **Undefined Behavior (UB)**\n\u003e\n\u003e C++ has a concept unique among mainstream languages: *undefined behavior*. When code invokes UB — signed integer overflow, reading past the end of an array, using a pointer after its object has been destroyed, uninitialized reads — the C++ standard places **no requirement whatsoever** on the compiler's output. The program may appear to work correctly on your machine and crash in production, or silently corrupt data. UB is why tools like AddressSanitizer and Valgrind exist (Phase 8). Learn to recognize common UB early, and enable compiler warnings (`-Wall -Wextra -Wpedantic`) to catch many of them at compile time.\n\n\u003e **Resources**\n\u003e - [learncpp.com — Chapters 1–7](https://www.learncpp.com) *(syntax, variables, control flow, functions, pointers)*\n\u003e - [cppreference.com — Fundamental types](https://en.cppreference.com/w/cpp/language/types)\n\u003e - 📖 *C++ Primer* (Lippman, Lajoie, Moo) — Chapters 1–6\n\n### Exercises\n\n1. Manually run all four compilation stages for a two-file program: `g++ -E` (preprocessing), `g++ -S` (to assembly), `g++ -c` (to object file), then link with `g++ main.o util.o -o app`. Inspect each output file.\n2. Create an ODR violation by defining the same non-inline function in two translation units and observe the linker error. Fix it with a forward declaration.\n3. Implement a command-line RPN (Reverse Polish Notation) calculator that reads expressions token by token from `std::cin` using `std::string`.\n\n---\n\n## Phase 3: Object-Oriented Programming (OOP)\n\n*Estimated time: ~3–4 weeks*\n\nC++ is a multi-paradigm language, but OOP remains heavily utilized.\n\n- **Classes and Objects:** Understand the difference between a blueprint (class) and an instance (object).\n- **Constructors, Destructors, and Member Initializer Lists:** Learn how objects are initialized and destroyed. Use the `: member(value)` member initializer list syntax in constructors — it is required for `const` members, reference members, and base class subobjects, and avoids the overhead of default-constructing then assigning.\n- **Static Members and Methods:** `static` member variables are shared across all instances of a class (not per-object). `static` member functions have no implicit `this` pointer and are callable without an instance. Common uses: instance counters, factory methods, Singleton.\n- **Encapsulation:** Practice hiding internal state using `public`, `private`, and `protected` access modifiers.\n- **Inheritance:** Learn how to create derived classes to reuse and extend code.\n- **Polymorphism:** Master virtual functions, pure virtual functions, and abstract classes to design flexible interfaces. Always use `override` on functions that override a base-class virtual — it prevents silent bugs when the base class signature changes. Use `final` to mark a class or function as non-derivable or non-overridable.\n- **Operator Overloading:** Overload `\u003c\u003c`, `\u003e\u003e`, `==`, `!=`, `\u003c`, `[]`, `()`, and arithmetic operators to give your types natural value semantics. Use `friend` functions for symmetric operators like `operator==`; use member functions for `operator[]` and `operator()`.\n- **RAII (Resource Acquisition Is Initialization):** The single most important C++ idiom. Bind every resource — memory, file handles, mutex locks, network sockets — to the lifetime of an object. The constructor acquires the resource; the destructor releases it. Because destructors run even when exceptions propagate, RAII makes code automatically exception-safe.\n- **Exception Handling:** Use `try`, `catch`, and `throw`. Mark functions `noexcept` when they cannot throw (destructors should almost always be `noexcept`). Learn the three exception safety guarantees: *basic* (no resource leaks, invariants intact), *strong* (operation either fully succeeds or has no effect — commit-or-rollback), and *no-throw* (operation never throws).\n- **Rule of Three / Five / Zero:** If your class manually manages a resource, you must define the destructor, copy constructor, and copy assignment operator (Rule of Three), and in C++11 also the move constructor and move assignment operator (Rule of Five). Prefer the **Rule of Zero**: design classes so that member smart pointers and STL containers own all resources, making all five special functions unnecessary.\n\n\u003e **Resources**\n\u003e - [learncpp.com — Chapters 13–17](https://www.learncpp.com) *(classes, inheritance, virtual functions, operator overloading)*\n\u003e - [C++ Core Guidelines — Class section](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#S-class)\n\u003e - 📖 *Effective C++* (Scott Meyers, 3rd Ed.) — Items on constructors, RAII, and polymorphism\n\n### Exercises\n\n1. Write an RAII `FileHandle` wrapper class. Verify it correctly closes the file even when an exception propagates out of the scope.\n2. Implement the Rule of Five for a `Buffer` class that owns a heap-allocated `char[]` array. Use AddressSanitizer to confirm no double-free or leak.\n3. Implement exception-safe copy assignment for `Buffer` using the copy-and-swap idiom.\n4. Overload `operator\u003c\u003c` for a `Matrix` class and `operator\u003c` so a `std::vector\u003cMatrix\u003e` can be sorted with `std::sort`.\n\n---\n\n## Phase 4: The Standard Template Library (STL)\n\n*Estimated time: ~3–4 weeks*\n\nDo not reinvent the wheel. The STL provides highly optimized, template-based data structures and algorithms.\n\n- **Sequential Containers:** Master `std::vector` (your default array), `std::array`, `std::deque`, and `std::list`. Use `std::vector` by default; switch to another container only when its specific complexity guarantees are genuinely needed.\n- **Associative Containers:** Learn `std::map`, `std::unordered_map`, `std::set`, and `std::unordered_set`. The ordered variants (`map`/`set`) use a red-black tree (O(log n)). The unordered variants are hash-based (average O(1) but with worse cache behavior).\n- **Container Adaptors:** `std::stack`, `std::queue`, and `std::priority_queue` wrap the sequence containers with a restricted interface.\n- **`std::pair` and `std::tuple`:** `std::map::value_type` is `std::pair\u003cconst Key, Value\u003e`. Use `std::tie` and C++17 structured bindings (`auto [key, val] = *it;`) to unpack them cleanly.\n- **Iterators:** Understand how to traverse containers using iterators rather than raw index loops. Learn the five iterator categories (input, output, forward, bidirectional, random-access) and when each applies. Use range-based `for` by default.\n- **Algorithms:** Learn `\u003calgorithm\u003e` functions: `std::sort`, `std::find`, `std::find_if`, `std::transform`, `std::accumulate`, `std::count_if`, `std::copy_if`, `std::remove_if`, and `std::partition`. Prefer algorithms over hand-written loops.\n- **`\u003crandom\u003e` Library:** Replace `rand()` (deprecated, statistically biased, global state) with `std::mt19937` paired with a distribution object like `std::uniform_int_distribution\u003cint\u003e` or `std::normal_distribution\u003cdouble\u003e`.\n\n\u003e ⚠️ **Iterator Invalidation**\n\u003e\n\u003e Modifying a container while holding iterators into it — or inserting past the end of a `vector` when it reallocates — silently invalidates those iterators, producing UB. Quick reference:\n\u003e\n\u003e | Container | Operations that invalidate iterators |\n\u003e |---|---|\n\u003e | `std::vector` | Any reallocation (`push_back` beyond capacity invalidates **all** iterators and pointers) |\n\u003e | `std::deque` | Insertions at front/back invalidate all iterators; middle insertions invalidate all |\n\u003e | `std::list` / `std::forward_list` | Only the erased element's iterator is invalidated |\n\u003e | `std::map` / `std::set` | Only the erased element's iterator is invalidated |\n\u003e | `std::unordered_map` / `std::unordered_set` | Rehashing (triggered by insert beyond load factor) invalidates **all** iterators |\n\n\u003e **Resources**\n\u003e - [learncpp.com — Chapters 16–17, 23](https://www.learncpp.com) *(arrays, STL, algorithms)*\n\u003e - 📖 *Effective STL* (Scott Meyers) — 50 specific ways to improve STL usage\n\u003e - [cppreference.com — Algorithms library](https://en.cppreference.com/w/cpp/algorithm)\n\u003e - [cppreference.com — Containers library](https://en.cppreference.com/w/cpp/container)\n\n### Exercises\n\n1. Benchmark `std::vector`, `std::list`, and `std::deque` for front-insert, back-insert, and sequential-iterate at sizes 1K, 100K, and 1M. Measure with `std::chrono::steady_clock`.\n2. Write a custom bidirectional iterator for a doubly-linked list node class that satisfies the `std::bidirectional_iterator` concept.\n3. Implement a phonebook using `std::map\u003cstd::string, std::string\u003e` with search, sorted-print, and erase operations — all implemented using STL algorithms, not hand-written loops.\n4. Generate 1 million random integers with `std::mt19937` + `std::uniform_int_distribution\u003cint\u003e` and bucket them into a 10-bin histogram.\n\n---\n\n## Phase 5: Templates \u0026 Generic Programming\n\n*Estimated time: ~3–4 weeks*\n\nGeneric programming allows you to write code that works for any type satisfying a set of requirements — without sacrificing performance. Every major component of the STL is built on templates.\n\n- **Function Templates:** Write a single function definition that the compiler instantiates into a concrete version for each type it is called with.\n- **Class Templates:** Parameterize entire classes by type. Learn **partial specialization** to provide a different implementation for a specific family of types (e.g., specializing `Container\u003cT*\u003e` for all pointer types).\n- **Non-Type Template Parameters:** Templates can be parameterized by values, not just types — e.g., `template\u003ctypename T, std::size_t N\u003e`, which is exactly how `std::array\u003cint, 5\u003e` is declared.\n- **Variadic Templates:** Accept any number of template arguments using `...Args`. Combined with **fold expressions** (`(f(args), ...)`, C++17), they replace recursive template metaprogramming for most common patterns.\n- **SFINAE (Substitution Failure Is Not An Error):** When the compiler substitutes a type into a template and the result is an invalid expression, that specialization is silently discarded rather than causing a compile error. The mechanism behind `std::enable_if` and conditional template overloading. (C++20 Concepts, covered in Phase 7, largely supersede SFINAE for new code.)\n- **`decltype` and `decltype(auto)`:** `decltype(expr)` queries the declared type of an expression without evaluating it. `decltype(auto)` deduces a return type that preserves reference and cv-qualifiers — essential for perfect-forwarding return types. Completes the type-deduction picture alongside `auto`.\n- **Compile-Time Programming:** Write `constexpr` functions evaluated at compile time when possible. Use `consteval` (C++20) to *require* compile-time evaluation. Use `static_assert` to embed compile-time correctness checks directly in the code. Explore type traits (`std::is_arithmetic_v`, `std::is_same_v`, `std::conditional_t`, `std::enable_if_t`) and `if constexpr` for compile-time branching inside template bodies.\n\n\u003e **Resources**\n\u003e - 📖 *Effective Modern C++* (Scott Meyers) — Items 1–3 *(type deduction for templates and `auto`)*\n\u003e - [learncpp.com — Chapters 11–13](https://www.learncpp.com) *(function templates, class templates)*\n\u003e - [cppreference.com — Templates](https://en.cppreference.com/w/cpp/language/templates)\n\u003e - [cppreference.com — Type traits](https://en.cppreference.com/w/cpp/header/type_traits)\n\n### Exercises\n\n1. Write a generic `clamp(value, lo, hi)` function template and verify it compiles and behaves correctly for `int`, `double`, and a custom `Duration` type.\n2. Implement a class template `TypedStack\u003cT\u003e` with a partial specialization for `bool` that packs booleans into a `uint64_t` bitfield.\n3. Write a variadic `print(args...)` function using a fold expression that prints all arguments separated by spaces, followed by a newline.\n4. Implement `constexpr uint64_t fibonacci(int n)` and verify three values at compile time using `static_assert`.\n5. Write a template function `process(x)` that uses `if constexpr` and `std::is_arithmetic_v` to double numeric arguments and reverse string arguments.\n\n---\n\n## Phase 6: Modern C++ Core (C++11 \u0026 C++14)\n\n*Estimated time: ~3–4 weeks*\n\nThis phase represents the shift from \"Old C++\" to \"Modern C++.\"\n\n⏩ *C++98/03 developers: this is the most important phase for you — every topic replaces a dangerous or verbose old pattern.*\n\n- **Smart Pointers:** Stop using raw `new` and `delete`. Master `std::unique_ptr` for exclusive ownership (zero overhead abstraction), `std::shared_ptr` for shared reference-counted ownership, and `std::weak_ptr` to observe a `shared_ptr`-managed object without extending its lifetime or creating reference cycles.\n- **Type Deduction:** Use `auto` to let the compiler deduce types — especially with iterator types and complex template return types. Use `decltype` and `decltype(auto)` to preserve value category in forwarding code.\n- **Lambdas:** Write anonymous, inline functions for use with STL algorithms. Understand capture clauses: `[=]` (capture all by value), `[\u0026]` (capture all by reference), and `[x, \u0026y]` (mixed). Use generic lambdas with `auto` parameters (C++14).\n- **Move Semantics:** The key to C++ performance. Learn rvalue references (`\u0026\u0026`), `std::move` (an unconditional cast to rvalue — it does not itself move anything; the move constructor or assignment does), and `std::forward\u003cT\u003e` (a conditional cast used in **forwarding references** `T\u0026\u0026` to preserve the argument's original lvalue or rvalue category). Together these enable zero-cost resource transfer and are essential for writing generic code that doesn't unnecessarily copy.\n- **`constexpr`:** Use `constexpr` to force the compiler to evaluate functions and variables at compile time.\n- **`std::function` and Callable Wrappers:** `std::function\u003cRet(Args...)\u003e` is a type-erased wrapper that stores any callable — lambdas, function pointers, bound member functions, or functors. Use it when you need to store a callback in a non-template context (class member, heterogeneous container, runtime dispatch). For performance-critical paths, prefer template parameters over `std::function` to avoid the virtual-dispatch overhead.\n\n\u003e **Resources**\n\u003e - 📖 *Effective Modern C++* (Scott Meyers) — Items 18–22 *(smart pointers)*, 23–29 *(rvalue references and move semantics)*, 31–34 *(lambdas)*\n\u003e - [learncpp.com — Chapters 20–22](https://www.learncpp.com) *(move semantics, smart pointers, lambdas)*\n\u003e - [CppCon \"Back to Basics: Smart Pointers\" on YouTube](https://www.youtube.com/@CppCon)\n\u003e - [CppCon \"Back to Basics: Move Semantics\" on YouTube](https://www.youtube.com/@CppCon)\n\n### Exercises\n\n1. Refactor a class hierarchy that uses raw `new`/`delete` to use `std::unique_ptr` and `std::shared_ptr`. Confirm no leaks with AddressSanitizer (`-fsanitize=address`).\n2. Implement a move constructor and move assignment operator for a `Buffer` class that owns a heap-allocated `std::byte[]` array. Use a `moved-from` state check to verify correctness.\n3. Write a `make_adder(n)` factory that returns a lambda capturing `n` by value, and store several adders in a `std::vector\u003cstd::function\u003cint(int)\u003e\u003e`.\n4. Implement a perfect-forwarding `invoke(f, args...)` wrapper that calls `f` with `args...`, preserving their value categories, and returns the result via `decltype(auto)`.\n\n---\n\n## Phase 7: Advanced Modern C++ (C++17, C++20, \u0026 C++23)\n\n*Estimated time: ~4–6 weeks*\n\nThis phase explores the cutting edge of the language, focusing on safer abstractions and highly expressive syntax.\n\n### Modern C++ Feature Evolution\n\n| Version | Key Features Introduced | Primary Use Case |\n| --- | --- | --- |\n| **C++17** | `std::optional`, `std::variant`, Structured Bindings | Safer return types (no more returning null pointers or sentinel values); cleaner variable unpacking with `auto [a, b] = pair;` |\n| **C++17** | `std::string_view`, `std::filesystem` | Zero-allocation string parsing; cross-platform file and directory manipulation |\n| **C++17** | `std::execution` policies | Trivially parallelise STL algorithms: `std::sort(std::execution::par, v.begin(), v.end())` |\n| **C++20** | Concepts | Add named constraints to templates: `template\u003cstd::integral T\u003e` produces human-readable errors instead of multi-page substitution failures |\n| **C++20** | Ranges | Functional-style composition: `v \\| views::filter(pred) \\| views::transform(f) \\| views::take(10)` — lazy, no intermediate allocations |\n| **C++20** | Modules | Replace `#include` with `import` for faster, more isolated compilation with no header-order bugs |\n| **C++20** | Coroutines | `co_await`, `co_yield`, `co_return` — the building blocks for lazy generators and async programming without callback pyramids |\n| **C++20** | `std::span` | Non-owning view over contiguous memory; replaces `T*` + size pairs in function signatures |\n| **C++23** | `std::expected`, `mdspan`, Deducing `this` | Rust-like error handling without exceptions; multi-dimensional array views; simplified CRTP pattern |\n\n**Concepts in depth:** A concept is a named Boolean predicate on template parameters checked at compile time. Constraining a template with `requires std::regular\u003cT\u003e` produces a diagnostic that names the unsatisfied concept rather than a pages-long substitution chain.\n\n**Ranges in depth:** The Ranges library (introduced in C++20) replaces iterator-pair based algorithms with range-based ones that compose with the `|` pipe operator. Views are lazy — no intermediate containers are allocated during composition.\n\n**Coroutines in depth:** A coroutine is a function that can suspend (`co_yield`, `co_await`) and be resumed later. They are the foundation for C++ generators, async I/O, and cooperative multitasking. The low-level machinery (`promise_type`, `coroutine_handle`) is complex; use a library abstraction (e.g., `cppcoro` or C++23's `std::generator`) in practice.\n\n\u003e **Resources**\n\u003e - [CppCon YouTube — \"Back to Basics\" and feature talks (2020–2024)](https://www.youtube.com/@CppCon)\n\u003e - [cppreference.com — Ranges library](https://en.cppreference.com/w/cpp/ranges)\n\u003e - [cppreference.com — Coroutines](https://en.cppreference.com/w/cpp/language/coroutines)\n\u003e - [cppreference.com — Concepts library](https://en.cppreference.com/w/cpp/concepts)\n\u003e - 📖 *C++ Crash Course* (Josh Lospinoso, 2020) — C++17 focused, fast-paced\n\n### Exercises\n\n1. Write an `Arithmetic` concept that accepts only arithmetic types and use it to constrain a `statistics\u003cT\u003e` class template. Confirm that instantiating with `std::string` produces a readable error.\n2. Build a lazy pipeline using `std::views` that reads a `std::vector\u003cstd::string\u003e`, filters out blank lines, transforms each to uppercase, and collects the first 10 results — without allocating intermediate vectors.\n3. Implement a `Generator\u003cuint64_t\u003e` coroutine that yields an infinite Fibonacci sequence. Consume the first 20 values using a range-based `for`.\n4. Convert a small utility header into a named C++20 module (`export module myutil;`) and update its `CMakeLists.txt` to use `target_sources(... FILE_SET CXX_MODULES ...)`.\n5. Parallelise a `std::transform` over a 10M-element `std::vector\u003cdouble\u003e` using `std::execution::par`. Benchmark against `std::execution::seq` using `std::chrono::steady_clock` and report the speedup.\n\n---\n\n## Phase 8: Professional Practices \u0026 Project Architecture\n\n*Estimated time: ~6–8 weeks*\n\nTo transition from a learner to a software engineer, you must master the ecosystem surrounding the language.\n\n- **Debugging:**\n  - **GDB** (Linux/macOS/WSL2): set breakpoints (`break`), step through code (`next`, `step`, `finish`), inspect state (`print`, `info locals`, `backtrace`), and perform post-mortem analysis with core dumps (`gdb ./app core`).\n  - **LLDB** (macOS/Clang): the native debugger for LLVM-built programs; equivalent capabilities with a slightly different command syntax.\n  - Both integrate with VS Code (via the C/C++ extension) and CLion.\n\n- **Memory Safety \u0026 Tooling:**\n  - **AddressSanitizer** (ASan, `-fsanitize=address`) and **UndefinedBehaviorSanitizer** (UBSan, `-fsanitize=undefined`) are compiler-injected runtime checks available on GCC and Clang on all platforms.\n  - **Valgrind** (Linux only — does not run natively on macOS or Windows; use WSL2) provides deeper heap analysis and the Callgrind profiler.\n  - On macOS, use ASan + LeakSanitizer or Instruments instead of Valgrind.\n\n- **Static Analysis:** Run **clang-tidy** (integrates with CMake via `CMAKE_CXX_CLANG_TIDY`) and **cppcheck** on every CI build. **include-what-you-use** finds unnecessary `#include` directives and speeds compilation.\n\n- **Unit Testing:** Write tests using **Google Test** (GTest) or **Catch2**. Structure tests into fixtures, use `ASSERT_*` (abort test on failure) vs. `EXPECT_*` (continue test on failure) correctly, and ensure tests are independent, fast, and deterministic.\n\n- **`std::chrono`:** The portable, type-safe timing library for benchmarking. Use `std::chrono::steady_clock::now()` to measure wall-clock intervals. Prefer this over `clock()` or OS-specific APIs.\n\n- **Profiling:** Measure before you optimize.\n  - **Linux:** `perf stat`, `perf record` + `perf report`, Valgrind/Callgrind\n  - **macOS:** Instruments (Xcode), `sample` command\n  - **Windows:** Visual Studio Profiler, vcperf + Windows Performance Analyzer\n  - **Cross-platform:** [Compiler Explorer (godbolt.org)](https://godbolt.org) — inspect generated assembly and compare codegen across compilers and optimization flags\n\n- **Multithreading \u0026 Concurrency:** Learn `\u003cthread\u003e`, `\u003cmutex\u003e`, `\u003ccondition_variable\u003e`, `\u003cfuture\u003e`, and `\u003catomic\u003e`. Understand the C++ memory model: acquire/release semantics and `std::memory_order` for lock-free programming. In C++20, prefer `std::jthread` (auto-joins on destruction, preventing detached-thread footguns) with `std::stop_token` for cooperative cancellation. Use `std::latch`, `std::barrier`, and `std::counting_semaphore` (C++20) for synchronization.\n\n- **Networking:** POSIX socket APIs (Linux/macOS) provide the foundation. For practical async networking, use **Asio** (standalone, header-only, no Boost required) — the de-facto standard and the basis for `std::net` (targeted for C++26). Asio works with C++20 coroutines for clean async code.\n\n- **Design Patterns in Modern C++:** Study how Singleton, Factory, Observer, Strategy, CRTP, PIMPL (Pointer to Implementation for ABI stability), and Type Erasure are implemented safely using modern C++ idioms.\n\n- **Data-Oriented Design (DOD) \u0026 Optimization:** Prefer structs-of-arrays over arrays-of-structs for cache performance on hot paths. Profile first, then optimize. Understand what the compiler generates before assuming something is slow.\n\n- **Continuous Integration:** Set up a **GitHub Actions** workflow that builds your project with CMake, runs your tests, runs clang-tidy, and runs ASan — on Linux, macOS, and Windows matrix runners simultaneously.\n\n\u003e **Resources**\n\u003e - [C++ Core Guidelines](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines) — 16 categories of best practices by Stroustrup and Herb Sutter\n\u003e - [Google Test documentation](https://google.github.io/googletest/)\n\u003e - [Catch2 documentation](https://github.com/catchorg/Catch2/blob/devel/docs/tutorial.md)\n\u003e - [Asio documentation](https://think-async.com/Asio/)\n\u003e - [CppCon \"Back to Basics: Concurrency\" on YouTube](https://www.youtube.com/@CppCon)\n\n### Exercises\n\n1. Introduce a deliberate use-after-free bug in a test program, locate it using GDB (`backtrace` + `info locals`), and confirm the precise line with AddressSanitizer.\n2. Run clang-tidy on a project with `--checks='modernize-*,cppcoreguidelines-*,readability-*'` and fix every warning without suppressing any with `NOLINT`.\n3. Profile a naïve matrix-multiplication function with `perf`/Instruments, measure baseline with `std::chrono`, optimize for cache locality (loop order, tiling), and report the speedup.\n4. Write a thread-safe bounded producer-consumer queue using `std::jthread`, `std::mutex`, and `std::condition_variable`. Add a `std::stop_token` cancellation path that allows clean shutdown.\n5. Set up a GitHub Actions workflow with a build matrix (GCC on Linux, Clang on macOS, MSVC on Windows) that compiles with CMake, runs unit tests, and runs ASan on every push to `main`.\n\n---\n\n## Capstone Projects\n\nApply everything by building increasingly ambitious projects. Each will expose gaps in your knowledge — that is the point.\n\n1. **CLI Task Manager** *(Phases 2–6)*\n   A command-line todo application: add, remove, list, and persist tasks to a file. Focus on `std::string` parsing, STL containers, RAII file handling, smart pointers, and unit testing with Catch2.\n\n2. **Generic Data Structures Library** *(Phases 4, 5, 6)*\n   Implement your own `DynArray\u003cT\u003e`, `HashMap\u003cK,V\u003e`, and `LinkedList\u003cT\u003e` with STL-compatible iterators, exception safety guarantees, unit tests, and benchmarks against their STL counterparts.\n\n3. **Multithreaded Log Aggregator** *(Phase 8 — Concurrency)*\n   A thread-safe log ingestion service: multiple `std::jthread` producers write entries to a shared queue; a consumer thread batches and flushes them to disk. Profile throughput with `std::chrono` and optimize for concurrency.\n\n4. **Async HTTP Server** *(Phases 7–8 — Coroutines + Networking)*\n   A minimal HTTP/1.1 server using **Asio** for async I/O and C++20 coroutines for request handling. Implement `GET` and `POST` endpoints serving a simple JSON API.\n\n5. **Custom STL-Compatible Allocator + Container** *(All Phases)*\n   Implement a memory arena allocator and a `vector`-like container that uses it. Implement all five iterator categories, the strong exception safety guarantee, and benchmark allocation performance against the default allocator using `std::chrono`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjomkz%2Flearn-modern-cpp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjomkz%2Flearn-modern-cpp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjomkz%2Flearn-modern-cpp/lists"}