C++ 23 cheatsheet

C++ 23: Classes, memory and templates

10 common C++ 23 tasks.

Define a class

A class with a constructor initializer list, a const method and private data.

class Account {
public:
    explicit Account(double balance) : balance_(balance) {}
    double balance() const { return balance_; }
private:
    double balance_;
};

Use polymorphism

Override a virtual function in a derived class. Always give a base class a virtual destructor.

struct Shape {
    virtual ~Shape() = default;
    virtual double area() const = 0;
};

struct Circle : Shape {
    double r;
    explicit Circle(double r) : r(r) {}
    double area() const override { return 3.14159 * r * r; }
};

Own an object with unique_ptr

Allocate an object that is deleted automatically when the pointer goes out of scope. Avoid raw new and delete.

auto p = std::make_unique<Account>(100.0);
std::cout << p->balance() << '\n';

Share ownership with shared_ptr

The object is deleted when the last shared_ptr to it goes away.

auto a = std::make_shared<Account>(50.0);
auto b = a;
std::cout << a.use_count() << '\n';

Move instead of copy

Transfer a resource to another object without copying it.

std::vector<int> big(1'000'000);
std::vector<int> other = std::move(big);

Lock a mutex safely

RAII locking releases the mutex even if an exception is thrown.

std::mutex m;
{
    std::lock_guard<std::mutex> lock(m);
    ++counter;
}

Write a function template

One function that works for any type that supports >.

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

Constrain a template with a concept

Accept only integral types and get clear error messages otherwise (C++20).

template <std::integral T>
T twice(T value) {
    return value * 2;
}

Capture variables in a lambda

Capture by value with [=] or by reference with [&], or name what you need.

int factor = 3;
auto times = [factor](int n) { return n * factor; };

Return a value or an error

std::expected holds a result or an error without exceptions (C++23).

std::expected<int, std::string> parse(const std::string& s) {
    try { return std::stoi(s); }
    catch (...) { return std::unexpected("not a number"); }
}

Was this page helpful?