Boring C++
Boring C++

C++ Quick Reference Card

5 min read

Appendix A: C++ Quick Reference Card

A condensed reference for the constructs used throughout this book. Each entry shows syntax followed by a brief note.


Declarations and Types

int x = 42;                    // integer variable
const int y = 42;              // immutable integer
constexpr int z = 42;          // compile-time constant
auto w = 42;                   // deduced type (int)
int arr[5] = {1,2,3,4,5};     // C array (prefer std::array)
int* p = &x;                   // pointer to int
const int* cp = &x;            // pointer to const int
int* const pc = &x;            // const pointer to int

Fixed-width integers (<cstdint>)

int8_t    int16_t    int32_t    int64_t
uint8_t   uint16_t   uint32_t   uint64_t

Casts

static_cast<double>(x)         // safe, checked at compile time
reinterpret_cast<char*>(p)     // reinterpret memory; use sparingly
const_cast<int*>(cp)           // remove const; almost never needed
dynamic_cast<Derived*>(base)   // safe downcast; returns nullptr on failure

Control Flow

if (cond) { ... } else if (cond2) { ... } else { ... }

if (int n = getValue(); n > 0) { ... }   // C++17: if with initializer

switch (x) {
    case 1: ... break;
    case 2: ... break;
    default: ...
}

for (int i = 0; i < n; ++i) { ... }     // traditional for
for (const auto& elem : container) { ... }  // range-based for
while (cond) { ... }
do { ... } while (cond);
break;    // exit loop or switch
continue; // next iteration
return value;

Functions

ReturnType functionName(ParamType param) { ... }

// Default argument
void greet(const std::string& name, const std::string& greeting = "Hello");

// Overloading: same name, different parameter types
int area(int side);
double area(double radius);

// Lambda
auto fn = [capture](ParamType param) -> ReturnType { return ...; };

// Lambda captures
[x]      // x by value
[&x]     // x by reference
[=]      // all by value
[&]      // all by reference
[=, &x]  // all by value, x by reference

// noexcept
void swap(T& a, T& b) noexcept { ... }

Classes

class MyClass {
public:
    MyClass(int x) : x_{x} {}      // constructor with member initializer
    ~MyClass() { ... }              // destructor
    int value() const { return x_; }  // const method
    void setValue(int x) { x_ = x; }  // non-const method

    MyClass(const MyClass&) = default;             // copy constructor
    MyClass& operator=(const MyClass&) = default;  // copy assignment
    MyClass(MyClass&&) noexcept = default;          // move constructor
    MyClass& operator=(MyClass&&) noexcept = default;  // move assignment

    MyClass(const MyClass&) = delete;  // prevent copying

private:
    int x_;
};

class Derived : public Base { ... };   // public inheritance
virtual void fn() = 0;                 // pure virtual (abstract)
void fn() override { ... }            // override virtual function
virtual ~Base() = default;             // virtual destructor (required in base)

Templates

template<typename T>
T maximum(const T& a, const T& b) { return a > b ? a : b; }

template<typename T>
class Stack { ... };

template<>
void printType<int>(const int& x) { ... }  // full specialization

// Concepts (C++20)
template<std::integral T>
T factorial(T n) { ... }

template<typename T>
concept Addable = requires(T a, T b) { { a + b } -> std::convertible_to<T>; };

Memory Management

// Smart pointers (<memory>)
auto up = std::make_unique<T>(args...);    // exclusive ownership
auto sp = std::make_shared<T>(args...);    // shared ownership
std::weak_ptr<T> wp = sp;                  // non-owning observer

up->method();   // access through unique_ptr
sp->method();   // access through shared_ptr
if (auto locked = wp.lock()) { ... }       // access through weak_ptr

// Move semantics
auto b = std::move(a);     // transfer ownership from a to b; a is now empty

// RAII: resource is released in destructor
class Resource {
    Resource() { /* acquire */ }
    ~Resource() { /* release */ }
};

Error Handling

// Exceptions
throw std::runtime_error{"message"};
try { ... }
catch (const std::runtime_error& e) { std::cerr << e.what(); }
catch (const std::exception& e) { ... }  // catch all standard exceptions

// optional (<optional>)
std::optional<int> findAge(const std::string& name);
if (auto age = findAge("Alice")) { std::cout << *age; }
int val = opt.value_or(-1);

// expected (<expected>, C++23)
std::expected<int, Error> parse(const std::string& s);
if (result) { use(*result); }
else { handle(result.error()); }

Standard Containers

std::vector<T>          // dynamic array; O(1) push_back
std::array<T, N>        // fixed-size array; stack-allocated
std::map<K, V>          // sorted key-value; O(log n)
std::unordered_map<K,V> // hashed key-value; O(1) avg
std::set<T>             // sorted unique values
std::unordered_set<T>   // hashed unique values
std::string             // owned character sequence
std::string_view        // non-owning string reference (C++17)
std::span<T>            // non-owning view of contiguous data (C++20)

Common Algorithms (<algorithm>)

std::sort(v.begin(), v.end());
std::sort(v.begin(), v.end(), cmp);
std::find(v.begin(), v.end(), value);       // returns iterator
std::find_if(v.begin(), v.end(), pred);
std::count_if(v.begin(), v.end(), pred);
std::transform(in.begin(), in.end(), out.begin(), fn);
std::accumulate(v.begin(), v.end(), init);  // <numeric>
std::remove_if(v.begin(), v.end(), pred);   // use with erase!
std::any_of / std::all_of / std::none_of
std::min_element / std::max_element
std::binary_search(v.begin(), v.end(), val); // requires sorted
std::unique(v.begin(), v.end());             // requires sorted; use with erase

Concurrency (<thread>, <mutex>, <future>)

std::thread t{fn, arg1, arg2};
t.join();   // wait for thread
t.detach(); // run independently

std::mutex m;
std::lock_guard<std::mutex> lock{m};    // scoped lock
std::unique_lock<std::mutex> ulock{m};  // flexible lock

std::condition_variable cv;
cv.wait(ulock, [&]() { return condition; });
cv.notify_one();
cv.notify_all();

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

auto future = std::async(std::launch::async, fn, args...);
auto result = future.get();  // blocks until ready; rethrows exceptions

Modern Features

// Structured bindings (C++17)
auto [key, val] = *map.begin();
auto [x, y, z] = myStruct;

// if constexpr (C++17)
if constexpr (std::is_integral_v<T>) { ... }

// std::format (C++20)
std::string s = std::format("Hello, {}! You are {} years old.", name, age);
std::cout << std::format("{:>10.2f}\n", 3.14159);

// Attributes
[[nodiscard]] int compute();
[[maybe_unused]] int debugCount;
[[deprecated("use newFn")]] void oldFn();

// Ranges (C++20)
auto view = data | std::views::filter(pred) | std::views::transform(fn);

// Concepts (C++20)
template<std::totally_ordered T> T clamp(T val, T lo, T hi);

Compiler Commands

# Compile
g++ -std=c++17 -Wall -Wextra -o output source.cpp
g++ -std=c++20 -Wall -Wextra -o output source.cpp
g++ -std=c++23 -Wall -Wextra -o output source.cpp

# With threading
g++ -std=c++17 -Wall -Wextra -pthread -o output source.cpp

# CMake
mkdir build && cd build && cmake .. && cmake --build .

# Sanitizers (invaluable for debugging)
g++ -fsanitize=address,undefined ...    # AddressSanitizer + UBSan
g++ -fsanitize=thread ...               # ThreadSanitizer
Boring C++

Modern C++ Mastery for Programmers Who Prefer Clarity Over Cleverness.

View book →