agentleFS
MuvonMuvon/octomind-tap/skills/programming-cpp/SKILL.md

programming-cpp

Skill6 starsChanged 8 months agoApache-2.0View on GitHub

Modern C++ practices for AI coding agents: architecture, RAII, value semantics, dependency and library selection. Use when writing or reviewing C++ code.

1 other project uses a version of this.

Adopted by

Most recently taken up by

The file

We split this skill into the rules it gives an agent

5 rules. About 0 are common, 2 are distinctive, and 3 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈2

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 3

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Every resource has an owner.

    line 24
  2. Very specific:

    Use unique_ptr for exclusive dynamic ownership.

    line 40
  3. Very specific:

    Use optional for expected absence, variant for closed alternatives, and expected<T, E> for explicit recoverable failure where compatible …

    line 48
  4. Distinctive:

    Keep casts and raw-memory manipulation at explicit interoperability boundaries.

    line 52
  5. Very specific:

    Prefer scoped task ownership.

    line 56

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Overview

Write modern C++ with value semantics, deterministic resource cleanup, and explicit lifetime contracts. As of 2026-10: C++23 is the published ISO standard; C++26 was technically completed by WG21 in March 2026 and awaits ISO publication, with compiler and library support still partial. Read build presets, compiler versions, selected language standard, standard-library implementation, and CI targets first. A compiler accepting -std=c++23 or -std=c++26 does not prove every facility of that standard is available. Recheck vendor support tables when adopting features.

Mental model

Every resource has an owner; every view has a lifetime. Prefer values and standard containers. RAII (resource acquisition is initialization) makes cleanup follow scope exit, including exceptions, but does not automatically prevent dangling references or unsynchronized shared mutation.

Modern features, gated by support

StandardUseful facilities
C++20Concepts, ranges, std::span, std::format, std::jthread/stop tokens, consteval, constinit.
C++23std::expected, std::print, std::ranges::to, explicit object parameters, std::mdspan.

Use concepts to express template requirements and ranges when the resulting pipeline is clearer than a loop. std::format is C++20; std::print is C++23. Neither guarantees a performance win for your workload. Modules and newer library features need compiler, library, and build-system support; don't introduce a migration or compatibility wrapper merely to use newer syntax. C++26 adds static reflection, contracts (pre, post, contract_assert), std::execution senders/receivers, standard-library hardening, and erroneous behavior for uninitialized reads; use them only where the project selects C++26 and every supported compiler implements the specific paper.

For safety on current toolchains, enable the implementation's library hardening in debug and CI builds where the project allows it (_GLIBCXX_ASSERTIONS for libstdc++, _LIBCPP_HARDENING_MODE for libc++), and run AddressSanitizer/UndefinedBehaviorSanitizer in tests; hardening converts some undefined behavior into traps, not into recoverable errors.

Ownership and lifetime

  • Let RAII members implement cleanup and copying/moving where they match the type's semantics: the rule of zero. For direct resource owners, define or delete the relevant special members deliberately.
  • Use unique_ptr for exclusive dynamic ownership; use shared_ptr only for shared lifetime, with weak_ptr where needed to avoid ownership cycles. Shared ownership does not synchronize the pointed-to object.
  • Raw pointers, references, string_view, and span ordinarily borrow. Don't retain or return them beyond their backing storage's lifetime. Container reallocation and mutation can invalidate views and iterators; lazy ranges may retain references to predicates and source storage.
  • Pass cheap values by value and expensive read-only inputs by const&. Transfer ownership explicitly. Return values naturally; return std::move(local) can prevent named return value optimization.
  • Standard-library moved-from objects are generally valid but unspecified unless documented otherwise. Check operation preconditions before reuse; custom types must define their own valid moved-from behavior.
  • A base intended for deletion through a base pointer needs a public virtual destructor; a protected nonvirtual destructor can prohibit that operation. Avoid object slicing when passing polymorphic values.

Types, errors, and numeric correctness

  • Use optional for expected absence, variant for closed alternatives, and expected<T, E> for explicit recoverable failure where compatible with the project's error model. Don't replace established exceptions globally.
  • An expected must be checked before unchecked value access. Preserve meaningful errors; don't convert failed parsing, I/O, or configuration into a successful empty object or zero.
  • Mark results [[nodiscard]] when discarding them usually violates the contract. Keep destructors nonthrowing; use an explicit operation when callers need to observe finalization errors.
  • Initialize values, validate narrowing conversions, and check arithmetic that can overflow. Signed integer overflow is undefined behavior. Parse complete input: successful prefix parsing must not silently accept trailing junk.
  • Keep casts and raw-memory manipulation at explicit interoperability boundaries. Document alignment, lifetime, aliasing, and ownership assumptions; don't bypass the type system to silence a diagnostic.

Concurrency and build boundaries

  • Prefer scoped task ownership. A jthread requests stop and joins when destroyed; stopping is cooperative, so blocking operations need a way to wake. Captured references must remain alive until work finishes.
  • Protect compound shared invariants with a mutex. Atomic variables alone don't make a multi-step algorithm safe, and std::atomic<T> is not guaranteed lock-free. Weaker memory ordering needs a correctness argument, not just a benchmark.
  • const& does not prove thread safety: another alias may mutate the same object. Establish lifetime and synchronization before sharing access.
  • In CMake, attach features, include paths, and dependencies to targets. Use PRIVATE, PUBLIC, and INTERFACE to express actual consumer requirements. Preserve the existing dependency manager and reproducible version policy.

Example

C++23: preserve failure as an explicit alternative instead of substituting a default.

#include <expected>

enum class WorkerError { non_positive };

[[nodiscard]] std::expected<unsigned, WorkerError> worker_count(int value) {
    if (value <= 0) {
        return std::unexpected(WorkerError::non_positive);
    }
    return static_cast<unsigned>(value);
}

Checklist

  • Features work across the project's compiler, library, standard, and target matrix.
  • Resources, borrowed lifetimes, moves, error paths, and synchronization have explicit contracts.
  • No silent defaults, unsafe narrowing, or unnecessary ownership/architecture expansion.
  • When authorized, use project formatting, warnings, focused tests, and applicable sanitizers. Check invalid input and lifetime boundaries; report checks skipped.

References

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.