# C++ Complete Reference

## C++23/C++20 Feature Matrix

### Compiler Support Status

| Feature                   | GCC     | Clang   | MSVC    | Standard | Production Ready |
| ------------------------- | ------- | ------- | ------- | -------- | ---------------- |
| **C++23 Features**        |         |         |         |          |                  |
| std::expected             | 13+     | 16+     | 19.35+  | C++23    | Yes              |
| std::print/std::println   | 14+     | 18+     | 19.37+  | C++23    | Yes              |
| std::format improvements  | 13+     | 17+     | 19.35+  | C++23    | Yes              |
| Deducing this             | 14+     | 18+     | 19.37+  | C++23    | Yes              |
| std::generator            | Not yet | Not yet | Not yet | C++23    | No (partial)     |
| Multidimensional operator | 13+     | 17+     | 19.35+  | C++23    | Yes              |
| if consteval              | 12+     | 14+     | 19.30+  | C++23    | Yes              |
| **C++20 Features**        |         |         |         |          |                  |
| Concepts                  | 10+     | 10+     | 19.26+  | C++20    | Yes              |
| Ranges                    | 10+     | 13+     | 19.30+  | C++20    | Yes              |
| Modules                   | 11+     | 16+     | 19.28+  | C++20    | Partial          |
| Coroutines                | 10+     | 5.0+    | 19.28+  | C++20    | Yes              |
| std::span                 | 10+     | 7.0+    | 19.26+  | C++20    | Yes              |
| std::format               | 13+     | 14+     | 19.29+  | C++20    | Yes              |
| std::jthread              | 10+     | 11+     | 19.28+  | C++20    | Yes              |
| std::latch/barrier        | 11+     | 11+     | 19.28+  | C++20    | Yes              |
| Three-way comparison      | 10+     | 10+     | 19.20+  | C++20    | Yes              |

### Build Requirements

Minimum Compiler Versions for C++23:

- GCC 13+ (recommended: GCC 14+)
- Clang 16+ (recommended: Clang 18+)
- MSVC 19.35+ (Visual Studio 2022 17.5+)
- CMake 3.28+

Minimum Compiler Versions for C++20:

- GCC 10+ (recommended: GCC 11+)
- Clang 10+ (recommended: Clang 13+)
- MSVC 19.26+ (Visual Studio 2019 16.6+)
- CMake 3.20+

---

## Standard Library Reference

### Containers

#### Sequence Containers

```cpp
#include <vector>
#include <deque>
#include <list>
#include <forward_list>
#include <array>

// std::vector - Dynamic array
std::vector<int> v{1, 2, 3};
v.push_back(4);              // Add element
v.emplace_back(5);           // Construct in-place
v.resize(10);                // Resize
v.reserve(100);              // Reserve capacity
auto size = v.size();        // Current size
auto cap = v.capacity();     // Allocated capacity

// std::array - Fixed-size array (C++20 aggregate CTAD)
std::array arr{1, 2, 3, 4, 5};  // Type deduced
arr.fill(0);                    // Fill all elements

// std::deque - Double-ended queue
std::deque<int> dq{1, 2, 3};
dq.push_front(0);
dq.push_back(4);

// std::list - Doubly linked list
std::list<int> lst{1, 2, 3};
lst.splice(lst.begin(), other_list);

// std::forward_list - Singly linked list
std::forward_list<int> flst{1, 2, 3};
flst.push_front(0);
```

#### Associative Containers

```cpp
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>

// std::set - Ordered unique elements
std::set<int> s{3, 1, 2};
s.insert(4);
s.erase(1);
auto it = s.find(2);
auto [iter, inserted] = s.insert(5);

// std::map - Ordered key-value pairs
std::map<std::string, int> m{
    {"one", 1}, {"two", 2}
};
m["three"] = 3;
m.insert_or_assign("two", 22);
auto result = m.try_emplace("four", 4);

// std::unordered_set - Hash set
std::unordered_set<std::string> uset{"a", "b", "c"};
uset.insert("d");
auto found = uset.contains("a");  // C++20

// std::unordered_map - Hash map
std::unordered_map<std::string, int> umap{
    {"x", 1}, {"y", 2}
};
umap.emplace("z", 3);

// C++23 heterogeneous lookup
struct TransparentHash {
    using is_transparent = void;
    auto operator()(std::string_view sv) const -> std::size_t {
        return std::hash<std::string_view>{}(sv);
    }
};

std::unordered_map<std::string, int, TransparentHash> tmap;
tmap.find("key");  // No temporary string creation
```

#### Container Adaptors

```cpp
#include <stack>
#include <queue>
#include <priority_queue>

// std::stack - LIFO
std::stack<int> stk;
stk.push(1);
auto top = stk.top();
stk.pop();

// std::queue - FIFO
std::queue<int> q;
q.push(1);
auto front = q.front();
q.pop();

// std::priority_queue - Heap
std::priority_queue<int> pq;
pq.push(5);
pq.push(2);
pq.push(8);
auto max = pq.top();  // 8
```

### Algorithms (C++20 Ranges)

```cpp
#include <algorithm>
#include <ranges>

std::vector<int> v{5, 2, 8, 1, 9};

// Sorting
std::ranges::sort(v);
std::ranges::sort(v, std::greater{});
std::ranges::sort(v, {}, &Person::age);  // Sort by member

// Searching
auto it = std::ranges::find(v, 5);
auto it2 = std::ranges::find_if(v, [](int n) { return n > 5; });
auto [min, max] = std::ranges::minmax_element(v);

// Transformation
std::vector<int> result;
std::ranges::transform(v, std::back_inserter(result),
    [](int n) { return n * 2; });

// Filtering
std::vector<int> filtered;
std::ranges::copy_if(v, std::back_inserter(filtered),
    [](int n) { return n % 2 == 0; });

// Counting
auto count = std::ranges::count(v, 5);
auto count_if = std::ranges::count_if(v, [](int n) { return n > 5; });

// Partitioning
auto pivot = std::ranges::partition(v, [](int n) { return n < 5; });

// Unique
std::ranges::sort(v);
auto [first, last] = std::ranges::unique(v);
v.erase(first, last);

// Accumulation (not in ranges, use std::)
#include <numeric>
auto sum = std::accumulate(v.begin(), v.end(), 0);
auto product = std::accumulate(v.begin(), v.end(), 1, std::multiplies{});
```

### String Operations

```cpp
#include <string>
#include <string_view>
#include <format>

// std::string
std::string s = "hello";
s += " world";
s.append("!");
auto sub = s.substr(0, 5);
auto pos = s.find("world");
s.replace(0, 5, "goodbye");

// std::string_view (C++17) - Non-owning view
std::string_view sv = "hello world";
auto first = sv.substr(0, 5);  // No allocation
auto starts = sv.starts_with("hello");  // C++20
auto ends = sv.ends_with("world");      // C++20
auto contains = sv.contains("lo");      // C++23

// std::format (C++20) - Type-safe formatting
auto formatted = std::format("Hello, {}!", "World");
auto with_args = std::format("{0} {1} {0}", "alpha", "beta");
auto aligned = std::format("{:>10}", "right");
auto decimal = std::format("{:.2f}", 3.14159);

// String conversions
int num = std::stoi("42");
double dbl = std::stod("3.14");
auto str_from_int = std::to_string(42);

// String algorithms
#include <algorithm>
std::string s2 = "HELLO";
std::ranges::transform(s2, s2.begin(), ::tolower);  // "hello"
```

### Smart Pointers

```cpp
#include <memory>

// std::unique_ptr - Exclusive ownership
auto ptr = std::make_unique<int>(42);
auto ptr2 = std::move(ptr);  // Transfer ownership
ptr.reset();                 // Delete and set to nullptr

// Custom deleter
auto file = std::unique_ptr<FILE, decltype(&fclose)>(
    std::fopen("file.txt", "r"),
    &fclose
);

// std::shared_ptr - Shared ownership
auto sptr = std::make_shared<int>(42);
auto sptr2 = sptr;  // Reference count = 2
auto count = sptr.use_count();

// std::weak_ptr - Non-owning reference
std::weak_ptr<int> wptr = sptr;
if (auto locked = wptr.lock()) {
    // Use locked shared_ptr
}

// std::make_unique_for_overwrite (C++20) - Skip initialization
auto uninit = std::make_unique_for_overwrite<int[]>(1000);

// std::shared_ptr with custom allocator
auto sptr3 = std::allocate_shared<int>(std::allocator<int>{}, 42);
```

### Utility Types

```cpp
#include <optional>
#include <variant>
#include <any>
#include <tuple>
#include <expected>  // C++23

// std::optional - May or may not contain a value
std::optional<int> opt = 42;
if (opt.has_value()) {
    auto val = *opt;
}
auto val_or = opt.value_or(0);

auto opt2 = std::optional<int>{};  // Empty
opt2.emplace(100);

// std::variant - Type-safe union
std::variant<int, std::string, double> var = 42;
var = "hello";
var = 3.14;

std::visit([](auto&& arg) {
    std::println("{}", arg);
}, var);

auto ptr = std::get_if<std::string>(&var);
if (ptr) {
    // Use *ptr
}

// std::any - Type-erased container
std::any a = 42;
a = std::string{"hello"};
auto str = std::any_cast<std::string>(a);

// std::tuple - Fixed-size heterogeneous collection
std::tuple<int, std::string, double> t{1, "hello", 3.14};
auto [i, s, d] = t;  // Structured binding
auto first = std::get<0>(t);

// std::expected (C++23) - Result type
std::expected<int, std::string> result = 42;
if (result) {
    auto value = *result;
} else {
    auto error = result.error();
}

// std::pair
std::pair<int, std::string> p{42, "answer"};
auto [num, text] = p;
```

---

## CMake Reference

### Project Configuration

```cmake
# Minimum version and project declaration
cmake_minimum_required(VERSION 3.28)
project(MyProject
    VERSION 1.0.0
    DESCRIPTION "My C++ Project"
    LANGUAGES CXX
)

# C++ standard
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

# Build type
if(NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE Release)
endif()

# Output directories
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)

# Export compile commands for IDE integration
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
```

### Compiler Options

```cmake
# Warning flags
add_compile_options(
    $<$<CXX_COMPILER_ID:GNU>:-Wall -Wextra -Wpedantic -Werror>
    $<$<CXX_COMPILER_ID:Clang>:-Wall -Wextra -Wpedantic -Werror>
    $<$<CXX_COMPILER_ID:MSVC>:/W4 /WX>
)

# Optimization flags
add_compile_options(
    $<$<AND:$<CONFIG:Release>,$<CXX_COMPILER_ID:GNU,Clang>>:-O3 -march=native>
    $<$<AND:$<CONFIG:Release>,$<CXX_COMPILER_ID:MSVC>>:/O2>
)

# Debug flags
add_compile_options(
    $<$<AND:$<CONFIG:Debug>,$<CXX_COMPILER_ID:GNU,Clang>>:-g -O0>
    $<$<AND:$<CONFIG:Debug>,$<CXX_COMPILER_ID:MSVC>>:/Od /Zi>
)

# Sanitizers (Debug only)
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
    add_compile_options(
        $<$<CXX_COMPILER_ID:GNU,Clang>:-fsanitize=adddess,undefined>
    )
    add_link_options(
        $<$<CXX_COMPILER_ID:GNU,Clang>:-fsanitize=adddess,undefined>
    )
endif()
```

### Target Configuration

```cmake
# Static library
add_library(mylib STATIC
    src/file1.cpp
    src/file2.cpp
)

target_include_directories(mylib
    PUBLIC
        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
        $<INSTALL_INTERFACE:include>
    PRIVATE
        ${CMAKE_CURRENT_SOURCE_DIR}/src
)

target_compile_features(mylib PUBLIC cxx_std_23)

target_link_libraries(mylib
    PUBLIC
        fmt::fmt
        spdlog::spdlog
    PRIVATE
        nlohmann_json::nlohmann_json
)

# Executable
add_executable(myapp src/main.cpp)
target_link_libraries(myapp PRIVATE mylib)

# Interface library (header-only)
add_library(myheaders INTERFACE)
target_include_directories(myheaders INTERFACE include/)
```

### Dependency Management

```cmake
# FetchContent
include(FetchContent)

FetchContent_Declare(fmt
    GIT_REPOSITORY https://github.com/fmtlib/fmt
    GIT_TAG 10.2.1
    GIT_SHALLOW TRUE
    SYSTEM  # Suppress warnings from dependency
)

FetchContent_MakeAvailable(fmt)

# Find package
find_package(Boost 1.75 REQUIRED COMPONENTS system filesystem)
target_link_libraries(mylib PUBLIC Boost::system Boost::filesystem)

# vcpkg integration
if(DEFINED ENV{VCPKG_ROOT})
    set(CMAKE_TOOLCHAIN_FILE "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake")
endif()

# pkg-config
find_package(PkgConfig REQUIRED)
pkg_check_modules(LIBCURL REQUIRED libcurl)
target_link_libraries(mylib PRIVATE ${LIBCURL_LIBRARIES})
target_include_directories(mylib PRIVATE ${LIBCURL_INCLUDE_DIRS})
```

### Testing with CTest

```cmake
# Enable testing
enable_testing()

# Add test executable
add_executable(mylib_tests
    tests/test1.cpp
    tests/test2.cpp
)

target_link_libraries(mylib_tests PRIVATE
    mylib
    GTest::gtest_main
)

# Discover tests
include(GoogleTest)
gtest_discover_tests(mylib_tests
    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
    PROPERTIES
        TIMEOUT 30
)

# Manual test registration
add_test(NAME mylib_test COMMAND mylib_tests)
set_tests_properties(mylib_test PROPERTIES
    TIMEOUT 60
    ENVIRONMENT "TEST_ENV_VAR=value"
)
```

### Installation

```cmake
# Install targets
install(TARGETS mylib myapp
    EXPORT MyProjectTargets
    LIBRARY DESTINATION lib
    ARCHIVE DESTINATION lib
    RUNTIME DESTINATION bin
    INCLUDES DESTINATION include
)

# Install headers
install(DIRECTORY include/mylib DESTINATION include)

# Install export configuration
install(EXPORT MyProjectTargets
    FILE MyProjectTargets.cmake
    NAMESPACE MyProject::
    DESTINATION lib/cmake/MyProject
)

# Generate config file
include(CMakePackageConfigHelpers)
configure_package_config_file(
    ${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in
    ${CMAKE_CURRENT_BINARY_DIR}/MyProjectConfig.cmake
    INSTALL_DESTINATION lib/cmake/MyProject
)

write_basic_package_version_file(
    ${CMAKE_CURRENT_BINARY_DIR}/MyProjectConfigVersion.cmake
    VERSION ${PROJECT_VERSION}
    COMPATIBILITY SameMajorVersion
)

install(FILES
    ${CMAKE_CURRENT_BINARY_DIR}/MyProjectConfig.cmake
    ${CMAKE_CURRENT_BINARY_DIR}/MyProjectConfigVersion.cmake
    DESTINATION lib/cmake/MyProject
)
```

### CMake Presets (CMakePresets.json)

```json
{
  "version": 6,
  "cmakeMinimumRequired": {
    "major": 3,
    "minor": 28,
    "patch": 0
  },
  "configurePresets": [
    {
      "name": "default",
      "hidden": true,
      "generator": "Ninja",
      "binaryDir": "${sourceDir}/build/${presetName}",
      "cacheVariables": {
        "CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
      }
    },
    {
      "name": "debug",
      "inherits": "default",
      "displayName": "Debug",
      "cacheVariables": {
        "CMAKE_BUILD_TYPE": "Debug"
      }
    },
    {
      "name": "release",
      "inherits": "default",
      "displayName": "Release",
      "cacheVariables": {
        "CMAKE_BUILD_TYPE": "Release"
      }
    }
  ],
  "buildPresets": [
    {
      "name": "debug",
      "configurePreset": "debug"
    },
    {
      "name": "release",
      "configurePreset": "release"
    }
  ],
  "testPresets": [
    {
      "name": "debug",
      "configurePreset": "debug",
      "output": { "outputOnFailure": true }
    }
  ]
}
```

---

## Compiler Flags Reference

### GCC/Clang Compiler Flags

```bash
# Standard selection
-std=c++23
-std=c++20
-std=gnu++23  # GNU extensions enabled

# Warning flags
-Wall          # Enable common warnings
-Wextra        # Additional warnings
-Wpedantic     # Strict ISO C++ compliance
-Werror        # Treat warnings as errors
-Wconversion   # Implicit conversions
-Wshadow       # Variable shadowing
-Wnon-virtual-dtor  # Non-virtual destructors

# Optimization levels
-O0            # No optimization (debug)
-O1            # Basic optimization
-O2            # Moderate optimization (default release)
-O3            # Aggressive optimization
-Os            # Optimize for size
-Ofast         # Aggressive with non-standard optimizations
-march=native  # Optimize for current CPU

# Debug information
-g             # Debug symbols
-g3            # Maximum debug info
-ggdb          # GDB-specific debug info
-gdwarf-4      # DWARF 4 debug format

# Sanitizers
-fsanitize=adddess              # Adddess sanitizer
-fsanitize=undefined            # Undefined behavior sanitizer
-fsanitize=thread               # Thread sanitizer
-fsanitize=memory               # Memory sanitizer (Clang only)
-fsanitize=leak                 # Leak sanitizer

# Link-time optimization
-flto          # Enable LTO
-flto=thin     # Thin LTO (Clang)

# Security hardening
-fstack-protector-strong        # Stack protection
-D_FORTIFY_SOURCE=2             # Fortify source
-Wformat -Wformat-security      # Format string security
-fPIE -pie                      # Position independent executable

# Performance profiling
-pg            # gprof profiling
-fprofile-generate  # Generate profile data
-fprofile-use       # Use profile data (PGO)
```

### MSVC Compiler Flags

```bash
# Standard selection
/std:c++latest
/std:c++20

# Warning flags
/W4            # High warning level
/WX            # Treat warnings as errors
/Wall          # All warnings (very verbose)

# Optimization levels
/Od            # Disable optimization (debug)
/O1            # Minimize size
/O2            # Maximize speed (default release)
/Ox            # Maximum optimization

# Debug information
/Zi            # Debug info in PDB
/Z7            # Debug info in obj files

# Runtime library
/MT            # Static runtime
/MD            # Dynamic runtime
/MTd           # Static runtime (debug)
/MDd           # Dynamic runtime (debug)

# Code generation
/EHsc          # Exception handling
/GR            # Enable RTTI
/GR-           # Disable RTTI
/arch:AVX2     # AVX2 instructions

# Security
/sdl           # Security development lifecycle checks
/guard:cf      # Control flow guard
/GS            # Buffer security check

# Optimization
/GL            # Whole program optimization
/LTCG          # Link-time code generation
```

---

## Build System Patterns

### Multi-Configuration Build

```bash
# CMake configure
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release

# Build specific configuration
cmake --build build --config Release

# Build with parallel jobs
cmake --build build -j$(nproc)

# Install
cmake --install build --prefix /usr/local
```

### Using CMake Presets

```bash
# List available presets
cmake --list-presets

# Configure with preset
cmake --preset=release

# Build with preset
cmake --build --preset=release

# Test with preset
ctest --preset=debug
```

### vcpkg Integration

```bash
# Install vcpkg
git clone https://github.com/microsoft/vcpkg
./vcpkg/bootstrap-vcpkg.sh

# Install packages
./vcpkg/vcpkg install fmt spdlog gtest

# Configure CMake with vcpkg
cmake -S . -B build \
    -DCMAKE_TOOLCHAIN_FILE=./vcpkg/scripts/buildsystems/vcpkg.cmake

# Using vcpkg.json (manifest mode)
# Create vcpkg.json in project root, vcpkg auto-installs dependencies
```

### Conan Integration

```bash
# Install Conan
pip install conan

# Create conanfile.txt
# [requires]
# fmt/10.2.1
# spdlog/1.13.0
# gtest/1.14.0
#
# [generators]
# CMakeDeps
# CMakeToolchain

# Install dependencies
conan install . --output-folder=build --build=missing

# Configure CMake
cmake -S . -B build \
    -DCMAKE_TOOLCHAIN_FILE=build/conan_toolchain.cmake

# Build
cmake --build build
```

---

## Memory Model and Concurrency

### Memory Order

```cpp
#include <atomic>

std::atomic<int> counter{0};

// Relaxed ordering - No synchronization
counter.store(1, std::memory_order_relaxed);
auto val = counter.load(std::memory_order_relaxed);

// Acquire-release ordering - Synchronize specific operations
counter.store(1, std::memory_order_release);
auto val2 = counter.load(std::memory_order_acquire);

// Sequential consistency - Strongest guarantee (default)
counter.store(1, std::memory_order_seq_cst);
auto val3 = counter.load(std::memory_order_seq_cst);

// Compare-exchange
int expected = 0;
bool success = counter.compare_exchange_strong(
    expected, 1,
    std::memory_order_acq_rel,
    std::memory_order_acquire
);

// Fetch operations
auto old = counter.fetch_add(1, std::memory_order_relaxed);
auto old2 = counter.fetch_sub(1, std::memory_order_relaxed);
```

### Thread Synchronization

```cpp
#include <mutex>
#include <shared_mutex>
#include <condition_variable>

// Mutex
std::mutex mtx;
{
    std::lock_guard lock(mtx);  // RAII lock
    // Critical section
}

{
    std::unique_lock lock(mtx);  // More flexible
    // Can unlock before scope ends
    lock.unlock();
}

// Shared mutex (C++17) - Multiple readers, single writer
std::shared_mutex smtx;

// Reader lock
{
    std::shared_lock lock(smtx);
    // Multiple readers allowed
}

// Writer lock
{
    std::unique_lock lock(smtx);
    // Exclusive access
}

// Condition variable
std::condition_variable cv;
std::mutex cv_mtx;
bool ready = false;

// Wait
std::unique_lock lock(cv_mtx);
cv.wait(lock, [] { return ready; });

// Notify
{
    std::lock_guard lock(cv_mtx);
    ready = true;
}
cv.notify_one();
cv.notify_all();
```

---

## Common Pitfalls and Best Practices

### Pitfall 1: Dangling References

```cpp
// BAD: Returns reference to local variable
auto& get_value() {
    int x = 42;
    return x;  // DANGER: x destroyed after return
}

// GOOD: Return by value or use heap allocation
auto get_value() {
    return 42;
}

auto get_ptr() {
    return std::make_unique<int>(42);
}
```

### Pitfall 2: Const Correctness

```cpp
// BAD: Missing const
class Widget {
    int value_;
public:
    int get_value() { return value_; }  // Not const-correct
};

// GOOD: Const methods for read-only operations
class Widget {
    int value_;
public:
    auto get_value() const -> int { return value_; }
    auto set_value(int v) -> void { value_ = v; }
};
```

### Pitfall 3: Resource Leaks

```cpp
// BAD: Manual resource management
void process_file() {
    FILE* file = fopen("data.txt", "r");
    // If exception thrown, file not closed
    process_data();
    fclose(file);
}

// GOOD: RAII with smart pointers or custom wrappers
void process_file() {
    auto file = std::unique_ptr<FILE, decltype(&fclose)>(
        fopen("data.txt", "r"),
        &fclose
    );
    if (!file) return;
    process_data();
    // Automatically closed
}
```

### Pitfall 4: Iterator Invalidation

```cpp
// BAD: Modifying container while iterating
std::vector<int> v{1, 2, 3, 4, 5};
for (auto it = v.begin(); it != v.end(); ++it) {
    if (*it % 2 == 0) {
        v.erase(it);  // DANGER: Iterator invalidated
    }
}

// GOOD: Use erase-remove idiom or update iterator
auto new_end = std::remove_if(v.begin(), v.end(),
    [](int n) { return n % 2 == 0; });
v.erase(new_end, v.end());

// Or update iterator after erase
for (auto it = v.begin(); it != v.end(); ) {
    if (*it % 2 == 0) {
        it = v.erase(it);  // erase returns next valid iterator
    } else {
        ++it;
    }
}
```

### Pitfall 5: Move Semantics Misuse

```cpp
// BAD: Using moved-from object
std::string s1 = "hello";
std::string s2 = std::move(s1);
std::cout << s1;  // DANGER: s1 in valid but unspecified state

// GOOD: Don't use moved-from objects (or reset them)
std::string s1 = "hello";
std::string s2 = std::move(s1);
s1 = "new value";  // Safe: assign new value
std::cout << s1;
```

### Best Practice 1: Use Modern Features

```cpp
// OLD: Manual memory management
Widget* widget = new Widget();
delete widget;

// MODERN: Smart pointers
auto widget = std::make_unique<Widget>();

// OLD: Raw loops
for (size_t i = 0; i < vec.size(); ++i) {
    process(vec[i]);
}

// MODERN: Range-based for
for (const auto& item : vec) {
    process(item);
}

// MODERN: Algorithms
std::ranges::for_each(vec, process);
```

### Best Practice 2: Const Everything Possible

```cpp
// Const member functions
class Counter {
    int count_ = 0;
public:
    auto get() const -> int { return count_; }
    auto increment() -> void { ++count_; }
};

// Const function parameters
auto process(const std::vector<int>& data) -> void {
    // Can't modify data
}

// Const local variables
const auto result = calculate();
```

### Best Practice 3: Use Structured Bindings

```cpp
// OLD: Manual unpacking
std::pair<int, std::string> p = get_data();
int id = p.first;
std::string name = p.second;

// MODERN: Structured binding
auto [id, name] = get_data();

// With containers
std::map<std::string, int> map;
for (const auto& [key, value] : map) {
    std::println("{}: {}", key, value);
}
```

### Best Practice 4: Prefer std::expected over Exceptions

```cpp
// Exceptions for exceptional cases
auto read_config() -> Config {
    if (!file_exists()) {
        throw std::runtime_error("Config not found");
    }
    return load_config();
}

// std::expected for expected errors
auto parse_int(std::string_view s)
    -> std::expected<int, ParseError> {
    // Returns error value, not exception
}
```

---

## Performance Optimization Patterns

### Small String Optimization (SSO)

```cpp
// Strings shorter than ~15-23 chars use stack storage
std::string small = "short";      // No heap allocation
std::string large = "very long string that exceeds SSO buffer";  // Heap allocated
```

### Reserve Capacity

```cpp
// BAD: Multiple reallocations
std::vector<int> v;
for (int i = 0; i < 1000; ++i) {
    v.push_back(i);  // May reallocate multiple times
}

// GOOD: Reserve upfront
std::vector<int> v;
v.reserve(1000);
for (int i = 0; i < 1000; ++i) {
    v.push_back(i);  // No reallocation
}
```

### Avoid Unnecessary Copies

```cpp
// BAD: Copy on every iteration
for (std::string s : vec) {  // Copy
    process(s);
}

// GOOD: Const reference
for (const auto& s : vec) {  // No copy
    process(s);
}

// When modifying
for (auto& s : vec) {
    s += "suffix";
}
```

### Move Instead of Copy

```cpp
// BAD: Expensive copy
std::vector<int> create_large_vector() {
    std::vector<int> v(1000000);
    return v;  // Copy elision usually applies, but not guaranteed
}

// GOOD: Explicit move (though modern compilers optimize this)
std::vector<int> create_large_vector() {
    std::vector<int> v(1000000);
    return v;  // NRVO (Named Return Value Optimization) applies
}

// When returning member
class Container {
    std::vector<int> data_;
public:
    auto take_data() -> std::vector<int> {
        return std::move(data_);  // Move required here
    }
};
```

---

Last Updated: 2026-01-10
Version: 1.0.0
