C++ cheat sheet

A scannable C++ reference: 10 short snippets across 6 topics, each linking back to the lesson it came from.

At a glance

TopicWhat it covers
Modern C++ basicsC++ is compiled and statically typed like C, but the same source only means one thing once you name a language versionlesson
Setting up C++: compilers, CMake and the build workflowThe three mainstream compilers are GCC, Clang/LLVM and MSVC. They agree on the language but differ in diagnosticlesson
References, const correctness and value categoriesstd::move does not move anything. It is a cast to an rvalue reference that makes the move constructor eligible. Afterlesson
Concurrency: threads, mutexes and asyncAlways wait with a predicate. A condition variable may wake spuriously and may be woken between the notification andlesson
CMake, dependencies and project structureThe single most valuable structural decision is to put all logic in a library target and keep the executable a thinlesson
C++20 and C++23 in practiceModules replace textual inclusion with an importable interface. They remove include-order dependencies, stop macrolesson

Quick snippets

Modern C++ basics

Compiling C++

g++ -std=c++20 -Wall -Wextra -Wpedantic -g main.cpp -o app
clang++ -std=c++20 -stdlib=libc++ -Wall -g main.cpp -o app   # clang

# several translation units: compile each, then link them together
g++ -std=c++20 -c shapes.cpp -o shapes.o
g++ -std=c++20 -c main.cpp -o main.o
g++ main.o shapes.o -o app

Replacements for the old habits

constexpr double kPi = 3.14159265358979;
enum class Colour { red, green, blue };

// structured bindings, C++17
auto [lo, hi] = std::pair{ 1, 9 };

// an if with an initialiser keeps a variable's scope tight
std::map<std::string, int> ages{ { "ada", 36 }, { "grace", 45 } };
if (auto it = ages.find("ada"); it != ages.end()) {
    std::cout << it->first << " is " << it->second << "\n";
}

Full lesson: Modern C++ basics →

Setting up C++: compilers, CMake and the build workflow

Compiler and standard

g++   --version
clang++ --version
cmake --version

# compile one translation unit with the warnings you actually want
g++ -std=c++20 -Wall -Wextra -Wpedantic -Wshadow -Wconversion -g -O2 main.cpp -o app

# feature-test a specific library facility instead of guessing
g++ -std=c++23 -dM -E -x c++ /dev/null | grep -i __cpp_lib

A minimal but correct CMake project

cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug          # configure
cmake --build build -j                                # build
ctest --test-dir build --output-on-failure            # test
cmake --build build --target install --config Release

# an out-of-tree build directory keeps the source tree clean;
# never configure in the source directory itself

Debug, sanitize and release configurations

# debug build with the sanitisers, driven from CMake options
cmake -S . -B build-asan -DCMAKE_BUILD_TYPE=Debug \
  -DCMAKE_CXX_FLAGS="-fsanitize=address,undefined -fno-omit-frame-pointer -g"
cmake --build build-asan -j && ctest --test-dir build-asan

# thread sanitizer needs its own tree: it cannot be combined with ASan
cmake -S . -B build-tsan -DCMAKE_BUILD_TYPE=Debug \
  -DCMAKE_CXX_FLAGS="-fsanitize=thread -g"

Full lesson: Setting up C++: compilers, CMake and the build workflow →

References, const correctness and value categories

Forwarding and copy elision

// const correctness as API documentation
class Buffer {
public:
    std::size_t size() const noexcept;                 // does not mutate
    char&       operator[](std::size_t i);             // mutable access
    const char& operator[](std::size_t i) const;       // read-only access
private:
    std::unique_ptr<char[]> data_;
    std::size_t size_ = 0;
};

Full lesson: References, const correctness and value categories →

Concurrency: threads, mutexes and async

Threads and RAII locking

// the classic deadlock, and the fix
void bad(A& a, B& b) {
    std::lock_guard<std::mutex> la(a.m);
    std::lock_guard<std::mutex> lb(b.m);   // deadlocks against the opposite order
}

void good(A& a, B& b) {
    std::scoped_lock lock(a.m, b.m);       // deadlock-free: locks in a fixed internal order
}

Full lesson: Concurrency: threads, mutexes and async →

CMake, dependencies and project structure

A layout that scales

project/
  CMakeLists.txt          # top level: options, subdirectories, nothing else
  cmake/                  # helper modules and toolchain files
  include/app/            # public headers, installed with the package
  src/                    # implementation, compiled into a library target
  tests/                  # unit tests, linked against the library
  bench/                  # benchmarks, built only in a Bench config
  third_party/            # vendored sources when fetching is not allowed
  .github/workflows/      # one job per compiler and sanitizer configuration

Full lesson: CMake, dependencies and project structure →

C++20 and C++23 in practice

Modules

// main.cpp — the consumer
import mathx;                        // no header guard, no macro leakage
#include <iostream>

int main() {
    Counter c;
    c.bump();
    std::cout << add(1, 2) << ' ' << c.value() << '\n';
}

Modules

cmake_minimum_required(VERSION 3.28)
project(modapp LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_SCAN_FOR_MODULES ON)     # requires a recent compiler and CMake

add_executable(modapp main.cpp mathx.ixx)
target_compile_features(modapp PRIVATE cxx_std_20)

Full lesson: C++20 and C++23 in practice →

FAQ

Is this C++ cheat sheet free to use?
Yes. No sign-up and no tracking: the page is static, every example is on the page itself, and you can print it or save it as a one-page reference.
Where do the examples come from?
Every snippet is taken from the 6 lessons of the C++ course on this site, and each section links back to the lesson it was pulled from.
How do I go deeper than a cheat sheet?
Open the full C++ course — it carries the worked explanations, the edge cases and the exercises behind every line here.

C C# Scala Lua Dart

Last refreshed 2026-09-27.