Skip to content
C++

C++ Idioms & Patterns

63 idioms and design patterns — from classic GoF patterns to C++-specific techniques like CRTP, type erasure, and policy-based design.

Creational
Structural
Behavioral
C++-Specific

Creational Patterns

Structural Patterns

Behavioral Patterns

Chain of Responsibility

Chain of Responsibility in C++ — linked handler chains, functional pipelines, middleware, and event bubbling with concrete patterns.

Basic
Command Pattern

Encapsulate operations as objects for deferred execution, undo/redo, queuing, and serialization — virtual hierarchies, std::function, and std::variant approaches.

Basic
Custom Iterators

Implementing correct C++ iterators—forward, bidirectional, random access, and C++20 ranges-compatible with sentinel types.

Intermediate
Mediator Pattern

C++ mediator pattern — event bus, signal/slot, and classic coordinator implementations with unsubscription, re-entrancy safety, and thread considerations.

Basic
Memento Pattern

Capture and restore object state in C++ without exposing internals — snapshots, undo/redo stacks, opaque mementos, and delta encoding.

Basic
Null Object Pattern

Replace nullptr returns and null checks with a do-nothing object that implements the full interface, eliminating guard code throughout callers.

Basic
Observer Pattern

Signal/slot, event buses, and safe observer lifetime in C++ using std::function, RAII tokens, weak_ptr tracking, and C++20 concepts.

Intermediate
State Machine Patterns

"C++ state machine implementations: enum+switch, std::variant+std::visit (C++17), function tables, and coroutine-based sequential machines (C++20)."

Intermediate
Strategy Pattern

Swap algorithms at runtime or compile time without touching the context. Virtual dispatch, std::function, template policies, and C++20 concepts compared.

Basic
Template Method Pattern

Define an algorithm's invariant skeleton in a non-virtual base-class method and defer variable steps to subclasses via NVI virtual hooks or CRTP for zero-overhead static dispatch.

Basic
Visitor Pattern

C++ visitor pattern — double dispatch, std::variant + std::visit, multi-variant dispatch, recursive ASTs, and the acyclic variant.

Intermediate

C++-Specific Idioms

Copy-and-Swap Idiom

Implement exception-safe assignment by taking the argument by value, swapping internals with *this, and letting the old state destroy itself on scope exit.

Intermediate
Expression Templates

Encode arithmetic expression trees as nested types so chained operations compile to a single loop with no intermediate heap allocations.

Advanced
Named Parameter Idiom

Simulate named function arguments in C++ using method-chaining builders, options structs, and C++20 designated initializers for self-documenting call sites.

Basic
Passkey Idiom

Grant selective access to private constructors and methods using an unforgeable token type, replacing coarse-grained friend declarations.

Basic
Perfect Forwarding

Preserve value categories through template wrappers using forwarding references, std::forward, and reference collapsing.

Intermediate
RAII

Resource Acquisition Is Initialization — tie resource lifetime to object lifetime for deterministic, exception-safe cleanup with zero overhead.

Basic
Runtime Polymorphism

Virtual dispatch, std::variant+std::visit, type erasure, and std::function compared — heap cost, extensibility, performance, and when to reach for each.

Intermediate
Scope Guard

Execute cleanup code at scope exit regardless of how the scope is left — generalized RAII without a dedicated wrapper class.

Basic
Tag Dispatch

Select function overloads at compile time by passing empty tag structs. The canonical pre-C++17 technique for type-based branching without SFINAE.

Intermediate
TypeList — Compile-Time Type Lists

"TypeList idiom: manipulate ordered sets of types at compile time with head/tail decomposition, filter, transform, and runtime dispatch patterns."

Advanced

Other Idioms

ADL Customization

Use argument-dependent lookup to let generic algorithms discover type-specific overloads defined in a type's own namespace, enabling non-intrusive extensibility.

Intermediate
Algebraic Types

Sum types and product types in C++: composing data with std::variant, std::optional, and structs to make illegal states unrepresentable.

Intermediate
Attorney-Client

Interpose a friend proxy class to grant selective, fine-grained access to a subset of another class's private members.

Intermediate
Barton-Nackman Trick

Inject non-template friend functions into a namespace via class template instantiation, discoverable exclusively through ADL at the point of use.

Advanced
Base From Member

Guarantee a member object is fully constructed before a dependent base class by promoting it into an earlier base class.

Intermediate
Compile-Time Dispatch

Selecting function implementations or code paths at compile time using type traits, tag types, if constexpr, and concepts — with no virtual dispatch overhead.

Intermediate
Continuation Passing

Pass a callable representing "what happens next" into a function instead of returning a value, enabling composable async pipelines and stack-safe recursion.

Intermediate
Copy-on-Write

Defer expensive deep copies until a mutation is actually needed by sharing immutable state with a reference count and cloning only when a write occurs.

Intermediate
Counted Pointer

A smart pointer idiom that tracks shared ownership via an atomic reference count, destroying the managed object when the last owner relinquishes it.

Intermediate
Detection Idiom

Compile-time trait detection via SFINAE and void_t to test whether a type supports a given expression, member, or nested type.

Advanced
Double Dispatch

Resolve a function call based on the runtime types of two objects, extending C++ virtual dispatch from one dimension to two.

Advanced
Erase-Remove

Remove elements from sequence containers by pairing std::remove/remove_if with erase, or use C++20's std::erase and std::erase_if for a cleaner one-liner.

Basic
Executor

Design pattern decoupling callable work from its execution context; formalized in C++26 as the scheduler/sender/receiver model in std::execution.

Advanced
Hidden Friend Idiom

Define non-member functions as friend inside a class body so they are only visible via ADL, preventing implicit conversions and speeding up overload resolution.

Intermediate
Lazy Initialization

Defer expensive object construction or computation to first use, paying the cost only when the value is actually needed.

Intermediate
Monadic Operations

Compose pipelines over std::optional and std::expected using and_then, transform, and or_else without manual value checks at each step.

Intermediate
Monostate

All instances share state via static members (design pattern), and std::monostate is a C++17 unit type that makes variant default-constructible.

Basic
Niebloids

Function objects used in std::ranges algorithms that suppress ADL and behave as non-customizable algorithm entry points in C++20.

Intermediate
Nifty Counter

A header-based reference-counting technique that guarantees a static object is initialized before any translation unit that includes its header uses it.

Intermediate
Overload Pattern

A compile-time technique that merges multiple callables into a single object exposing all their operator() overloads via variadic using declarations.

Intermediate
Pointer to Member

A typed handle to a specific non-static member of a class, invoked against any instance of that class using the .* and ->* operators.

Intermediate
Return Type Resolver

A proxy object with conversion operators lets one function produce different return types, selected implicitly by the assignment context.

Intermediate
SFINAE

Substitution Failure Is Not An Error — the compiler silently discards template specialisations whose type substitution produces an invalid expression, enabling fine-grained overload control.

Advanced
Small Buffer Optimization

Embed a fixed-size inline buffer inside an object to eliminate heap allocation for small payloads, trading object size for latency and cache locality.

Advanced
Thread-Safe Singleton

Guaranteeing exactly-once construction of a singleton across concurrent threads using function-local statics, std::call_once, or atomic DCLP.

Advanced
Value Semantics

Objects with value semantics behave like built-in types—each copy is independent, mutations don't propagate across instances, and ownership is unambiguous.

Basic
Virtual Friend Function

Simulate virtual behavior in non-member friend functions by delegating to a protected virtual member function.

Basic