C++ Expert
RAII owns every resource; values move, don't copy. Make ownership explicit, lean on the STL, and treat undefined behavior as a bug to prevent — not a surprise to debug.
When to Use
- Writing or reviewing C++.
- Modern features (C++17/20/23), templates/metaprogramming, STL.
- Performance/memory tuning; smart pointers and ownership.
- Compile errors, crashes, leaks, or undefined behavior (UB).
When NOT to Use
- Another language → relevant language skill.
- Contest algorithms (language incidental) →
competitive-programming-expert.
- System/architecture design →
software-architect.
Core Principles
1. Modern by default
- Target C++17/20 unless constrained. Prefer
auto, range-based for, structured bindings, std::optional/variant/string_view/span.
- Constrain templates with Concepts (C++20) or
static_assert so errors surface at the call site, not deep in instantiation.
2. Ownership & RAII
- No owning raw pointers.
std::unique_ptr for sole ownership, shared_ptr only when ownership is genuinely shared; create with make_unique/make_shared. Raw pointers/references are non-owning observers.
- Every resource (memory, file, lock, socket) is owned by an object that releases it in its destructor. Locks via
std::scoped_lock/lock_guard.
- Follow the Rule of 0 (no manual special members) — or Rule of 5 if you manage a resource directly.
3. Value semantics & performance
- Pass
const& for read-only, by value + std::move to sink, string_view/span for non-owning views. Rely on (N)RVO — return by value.
- Avoid premature
shared_ptr (atomic refcount cost) and needless copies; emplace_back, reserve. Choose containers deliberately (vector by default). constexpr/consteval for compile-time work. Profile before micro-optimizing.
4. Avoid UB proactively
- Dangling refs/views, use-after-move, out-of-bounds, signed overflow, uninitialized reads, iterator invalidation, data races. Build with warnings (
-Wall -Wextra), sanitizers (ASan/UBSan/TSan), and tools (clang-tidy).
Common Mistakes
- Owning raw
new/delete → leaks/double-free; use smart pointers + RAII.
- Returning
string_view/reference to a local/temporary → dangling.
- Using a moved-from object beyond a valid-but-unspecified state.
shared_ptr everywhere → atomic overhead + cycles (use weak_ptr to break).
- C-style casts /
reinterpret_cast → use static_cast/dynamic_cast.
- Iterator/reference invalidation after container growth/erase.
std::endl in loops → forced flush; use '\n'.
Examples
RAII + move-only ownership (C++17)
#include <memory>
#include <string>
#include <utility>
class Connection {
public:
explicit Connection(std::string dsn) : dsn_(std::move(dsn)) { /* open */ }
~Connection() noexcept { /* close */ }
Connection(const Connection&) = delete; // non-copyable
Connection& operator=(const Connection&) = delete;
Connection(Connection&&) noexcept = default; // movable
Connection& operator=(Connection&&) noexcept = default;
private:
std::string dsn_;
};
auto make_conn(std::string dsn) {
return std::make_unique<Connection>(std::move(dsn)); // ownership is explicit
}
Concept-constrained template (clear errors, no overflow)
#include <concepts>
template <std::integral T>
constexpr T midpoint(T a, T b) noexcept { return a + (b - a) / 2; }
See Also
competitive-programming-expert — STL-heavy solutions and constant-factor tuning.
performance-expert — profiling and allocation reduction.
rust-expert — comparing systems-language ownership models.
rules/cpp-style-guide.md — enforceable style rules.
1---2name: cpp-expert3description: Expert modern C++ (17/20/23): safe, performant code, RAII, move semantics, templates/concepts, and UB diagnosis. Trigger keywords: C++, C++17, C++20, C++23, smart pointer, unique_ptr, RAII, move semantics, rvalue, template, concept, STL, undefined behavior, constexpr, memory, dangling. Use for C++ implementation, optimization, generic programming, or UB/memory issues.4---56# C++ Expert78> RAII owns every resource; values move, don't copy. Make ownership explicit, lean on the STL, and treat undefined behavior as a bug to prevent — not a surprise to debug.910## When to Use11- Writing or reviewing C++.12- Modern features (C++17/20/23), templates/metaprogramming, STL.13- Performance/memory tuning; smart pointers and ownership.14- Compile errors, crashes, leaks, or undefined behavior (UB).1516## When NOT to Use17- Another language → relevant language skill.18- Contest algorithms (language incidental) → `competitive-programming-expert`.19- System/architecture design → `software-architect`.2021## Core Principles2223### 1. Modern by default24- Target C++17/20 unless constrained. Prefer `auto`, range-based `for`, structured bindings, `std::optional`/`variant`/`string_view`/`span`.25- Constrain templates with **Concepts** (C++20) or `static_assert` so errors surface at the call site, not deep in instantiation.2627### 2. Ownership & RAII28- No owning raw pointers. `std::unique_ptr` for sole ownership, `shared_ptr` only when ownership is genuinely shared; create with `make_unique`/`make_shared`. Raw pointers/references are non-owning observers.29- Every resource (memory, file, lock, socket) is owned by an object that releases it in its destructor. Locks via `std::scoped_lock`/`lock_guard`.30- Follow the Rule of 0 (no manual special members) — or Rule of 5 if you manage a resource directly.3132### 3. Value semantics & performance33- Pass `const&` for read-only, by value + `std::move` to sink, `string_view`/`span` for non-owning views. Rely on (N)RVO — return by value.34- Avoid premature `shared_ptr` (atomic refcount cost) and needless copies; `emplace_back`, `reserve`. Choose containers deliberately (`vector` by default). `constexpr`/`consteval` for compile-time work. Profile before micro-optimizing.3536### 4. Avoid UB proactively37- Dangling refs/views, use-after-move, out-of-bounds, signed overflow, uninitialized reads, iterator invalidation, data races. Build with warnings (`-Wall -Wextra`), sanitizers (ASan/UBSan/TSan), and tools (clang-tidy).3839## Common Mistakes40- **Owning raw `new`/`delete`** → leaks/double-free; use smart pointers + RAII.41- **Returning `string_view`/reference to a local/temporary** → dangling.42- **Using a moved-from object** beyond a valid-but-unspecified state.43- **`shared_ptr` everywhere** → atomic overhead + cycles (use `weak_ptr` to break).44- **C-style casts / `reinterpret_cast`** → use `static_cast`/`dynamic_cast`.45- **Iterator/reference invalidation** after container growth/erase.46- **`std::endl` in loops** → forced flush; use `'\n'`.4748## Examples4950**RAII + move-only ownership (C++17)**51```cpp52#include <memory>53#include <string>54#include <utility>5556class Connection {57public:58 explicit Connection(std::string dsn) : dsn_(std::move(dsn)) { /* open */ }59 ~Connection() noexcept { /* close */ }60 Connection(const Connection&) = delete; // non-copyable61 Connection& operator=(const Connection&) = delete;62 Connection(Connection&&) noexcept = default; // movable63 Connection& operator=(Connection&&) noexcept = default;64private:65 std::string dsn_;66};6768auto make_conn(std::string dsn) {69 return std::make_unique<Connection>(std::move(dsn)); // ownership is explicit70}71```7273**Concept-constrained template (clear errors, no overflow)**74```cpp75#include <concepts>76template <std::integral T>77constexpr T midpoint(T a, T b) noexcept { return a + (b - a) / 2; }78```7980## See Also81- `competitive-programming-expert` — STL-heavy solutions and constant-factor tuning.82- `performance-expert` — profiling and allocation reduction.83- `rust-expert` — comparing systems-language ownership models.84- `rules/cpp-style-guide.md` — enforceable style rules.