C++23 New Features
std::expected for Error Handling: Create an enum class ParseError with InvalidFormat and OutOfRange values. Define a parse_int function that takes std::string_view and returns std::expected containing either int or ParseError. Inside, use a try-catch block to call std::stoi. Catch std::invalid_argument and return std::unexpected with InvalidFormat, catch std::out_of_range and return std::unexpected with OutOfRange. On success, return the parsed value directly. Usage involves checking the result with if(result) and accessing the value with asterisk operator or handling the error case.
std::print for Type-Safe Output: Include the print header and use std::println for formatted output with curly brace placeholders. Supports format specifiers like colon followed by hash x for hexadecimal or colon followed by .2f for floating point precision.
Deducing This (Explicit Object Parameter): Define a Builder class with a data_ member string. Create a template method append with template parameter Self that takes this Self and and a string_view parameter. Forward self with std::forward and return Self and and. This enables chaining on both lvalue and rvalue objects.
C++20 Features
Concepts and Constraints: Define a Hashable concept using requires expression that checks if std::hash can produce a std::size_t. Create template functions with requires clauses to constrain Container types to std::ranges::range. Use abbreviated syntax with std::integral auto for simple constraints on individual parameters.
Modules: Create a module interface file with .cppm extension. Use export module followed by the module name. Define an export namespace containing template functions. In consumer files, use import statements instead of include directives. Import std for standard library access in module-aware compilers.
Ranges Library: Define structs for data types like Person with name and age fields. Use pipe operator to chain views::filter with a lambda checking conditions, then views::transform to extract fields. Iterate with range-based for loops. Use std::ranges::sort with projections for sorting by member fields.
RAII and Resource Management
Rule of Five: Implement a Resource class managing a raw pointer and size. The constructor allocates with new array syntax. The destructor calls delete array. Copy constructor allocates new memory and uses std::copy. Copy assignment uses copy-and-swap idiom by creating a temp and calling swap. Move constructor uses std::exchange to take ownership and null the source. Move assignment deletes current data and uses std::exchange. The swap member swaps both pointer and size members.
Smart Pointer Patterns: For unique ownership, create static factory methods returning std::unique_ptr via std::make_unique. For shared ownership with cycles, use std::enable_shared_from_this as a base class. Store children in std::vector of shared_ptr and parent as std::weak_ptr to break reference cycles. Use weak_from_this when setting parent relationships.
CMake Modern Patterns
CMakeLists.txt Structure for C++23: Begin with cmake_minimum_required VERSION 3.28 and project declaration. Set CMAKE_CXX_STANDARD to 23 with STANDARD_REQUIRED ON. Enable CMAKE_EXPORT_COMPILE_COMMANDS. Use generator expressions for compiler-specific warning flags, checking CXX_COMPILER_ID for GNU, Clang, or MSVC. Use FetchContent to declare dependencies with GIT_REPOSITORY and GIT_TAG parameters. Call FetchContent_MakeAvailable to download and configure. Create libraries with add_library, set include directories with target_include_directories, and link with target_link_libraries. For testing, enable_testing, add test executables, link GTest::gtest_main, and use gtest_discover_tests.
Concurrency
std::jthread and Stop Tokens: Define worker functions taking std::stop_token parameter. Loop while stop_requested returns false, performing work and sleeping. Create std::jthread objects passing the worker function. Call request_stop to signal termination. The thread destructor automatically joins.
Synchronization Primitives: Use std::latch for one-time synchronization by calling count_down. Use std::barrier for repeated synchronization with arrive_and_wait. Use std::counting_semaphore for resource pools with acquire and release calls.
---