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
| Topic | What it covers | |
|---|---|---|
| Modern C++ basics | C++ is compiled and statically typed like C, but the same source only means one thing once you name a language version | lesson |
| Setting up C++: compilers, CMake and the build workflow | The three mainstream compilers are GCC, Clang/LLVM and MSVC. They agree on the language but differ in diagnostic | lesson |
| References, const correctness and value categories | std::move does not move anything. It is a cast to an rvalue reference that makes the move constructor eligible. After | lesson |
| Concurrency: threads, mutexes and async | Always wait with a predicate. A condition variable may wake spuriously and may be woken between the notification and | lesson |
| CMake, dependencies and project structure | The single most valuable structural decision is to put all logic in a library target and keep the executable a thin | lesson |
| C++20 and C++23 in practice | Modules replace textual inclusion with an importable interface. They remove include-order dependencies, stop macro | lesson |
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 configurationFull 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.
Related cheat sheets
Last refreshed 2026-09-27.