[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M71MPQ28HD7P1ZADEV4X7JA8":3,"skill-same:01M71MPQ28HD7P1ZADEV4X7JA8":86},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":15,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":44,"linkOnly":45,"markdownContent":46,"markdownBody":47,"frontMatter":48,"refName":58,"commitSha":59,"skillDirectory":60,"forksCount":61,"repositoryHtmlUrl":62,"repositoryHomepageUrl":63,"ownerHtmlUrl":64,"ownerBlogUrl":65,"ownerDescription":6,"updatedAt":66,"install":67,"resources":80},"01M71MPQ28HD7P1ZADEV4X7JA8","cpp-coding-standards",null,"Use when writing, reviewing or refactoring modern C++17\u002F20\u002F23 code against the C++ Core Guidelines: RAII, immutability, type safety and interface rules. A rule catalogue; for building high-performance C++ with templates, concurrency and SIMD use cpp-pro.","monoes\u002Fmonomind","monoes","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F276744696?v=4","01M71KWF37AJ2NJBP3KWBVSDGT","01M71KWF4CSF8ADH0M6HA09VD2",23,"MIT","https:\u002F\u002Fgithub.com\u002Fmonoes\u002Fmonomind\u002Fblob\u002Fmain\u002Fpackages\u002F@monomind\u002Fcli\u002Forg-skills\u002Fcpp-coding-standards\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fmonoes\u002Fmonomind\u002Fblob\u002Fmain\u002Fpackages\u002F@monomind\u002Fcli\u002Forg-skills\u002Fcpp-coding-standards\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43],"coding standards","coding","standards","cpp coding standards","cpp","catalogue","context","Safety","Type Safety","refactoring","concurrency","review","code-review","code","query","when","high-performance","writing","interface","performance","2026-11-10 10:56:23",false,"---\nname: cpp-coding-standards\ndescription: \"Use when writing, reviewing or refactoring modern C++17\u002F20\u002F23 code against the C++ Core Guidelines: RAII, immutability, type safety and interface rules. A rule catalogue; for building high-performance C++ with templates, concurrency and SIMD use cpp-pro.\"\ntags: [\"engineering\",\"cpp\",\"coding-standards\",\"code-review\"]\ntools: [\"monograph_query\",\"monograph_context\"]\nlicense: MIT\nsource: https:\u002F\u002Fgithub.com\u002Faffaan-m\u002FECC\nsource_path: \"skills\u002Fcpp-coding-standards\"\nsource_commit: bf70150eb2df8070024e5bdf08e4aa08959e2735\n---\n# C++ Coding Standards (C++ Core Guidelines)\n\nComprehensive coding standards for modern C++ (C++17\u002F20\u002F23) derived from the [C++ Core Guidelines](https:\u002F\u002Fisocpp.github.io\u002FCppCoreGuidelines\u002FCppCoreGuidelines). Enforces type safety, resource safety, immutability, and clarity.\n\n## When to Use\n\n- Writing new C++ code (classes, functions, templates)\n- Reviewing or refactoring existing C++ code\n- Making architectural decisions in C++ projects\n- Enforcing consistent style across a C++ codebase\n- Choosing between language features (e.g., `enum` vs `enum class`, raw pointer vs smart pointer)\n\n### When NOT to Use\n\n- Non-C++ projects\n- Legacy C codebases that cannot adopt modern C++ features\n- Embedded\u002Fbare-metal contexts where specific guidelines conflict with hardware constraints (adapt selectively)\n\n## Cross-Cutting Principles\n\nThese themes recur across the entire guidelines and form the foundation:\n\n1. **RAII everywhere** (P.8, R.1, E.6, CP.20): Bind resource lifetime to object lifetime\n2. **Immutability by default** (P.10, Con.1-5, ES.25): Start with `const`\u002F`constexpr`; mutability is the exception\n3. **Type safety** (P.4, I.4, ES.46-49, Enum.3): Use the type system to prevent errors at compile time\n4. **Express intent** (P.3, F.1, NL.1-2, T.10): Names, types, and concepts should communicate purpose\n5. **Minimize complexity** (F.2-3, ES.5, Per.4-5): Simple code is correct code\n6. **Value semantics over pointer semantics** (C.10, R.3-5, F.20, CP.31): Prefer returning by value and scoped objects\n\n## Philosophy & Interfaces (P.*, I.*)\n\n### Key Rules\n\n| Rule | Summary |\n|------|---------|\n| **P.1** | Express ideas directly in code |\n| **P.3** | Express intent |\n| **P.4** | Ideally, a program should be statically type safe |\n| **P.5** | Prefer compile-time checking to run-time checking |\n| **P.8** | Don't leak any resources |\n| **P.10** | Prefer immutable data to mutable data |\n| **I.1** | Make interfaces explicit |\n| **I.2** | Avoid non-const global variables |\n| **I.4** | Make interfaces precisely and strongly typed |\n| **I.11** | Never transfer ownership by a raw pointer or reference |\n| **I.23** | Keep the number of function arguments low |\n\n### DO\n\n```cpp\n\u002F\u002F P.10 + I.4: Immutable, strongly typed interface\nstruct Temperature {\n    double kelvin;\n};\n\nTemperature boil(const Temperature& water);\n```\n\n### DON'T\n\n```cpp\n\u002F\u002F Weak interface: unclear ownership, unclear units\ndouble boil(double* temp);\n\n\u002F\u002F Non-const global variable\nint g_counter = 0;  \u002F\u002F I.2 violation\n```\n\n## Functions (F.*)\n\n### Key Rules\n\n| Rule | Summary |\n|------|---------|\n| **F.1** | Package meaningful operations as carefully named functions |\n| **F.2** | A function should perform a single logical operation |\n| **F.3** | Keep functions short and simple |\n| **F.4** | If a function might be evaluated at compile time, declare it `constexpr` |\n| **F.6** | If your function must not throw, declare it `noexcept` |\n| **F.8** | Prefer pure functions |\n| **F.16** | For \"in\" parameters, pass cheaply-copied types by value and others by `const&` |\n| **F.20** | For \"out\" values, prefer return values to output parameters |\n| **F.21** | To return multiple \"out\" values, prefer returning a struct |\n| **F.43** | Never return a pointer or reference to a local object |\n\n### Parameter Passing\n\n```cpp\n\u002F\u002F F.16: Cheap types by value, others by const&\nvoid print(int x);                           \u002F\u002F cheap: by value\nvoid analyze(const std::string& data);       \u002F\u002F expensive: by const&\nvoid transform(std::string s);               \u002F\u002F sink: by value (will move)\n\n\u002F\u002F F.20 + F.21: Return values, not output parameters\nstruct ParseResult {\n    std::string token;\n    int position;\n};\n\nParseResult parse(std::string_view input);   \u002F\u002F GOOD: return struct\n\n\u002F\u002F BAD: output parameters\nvoid parse(std::string_view input,\n           std::string& token, int& pos);    \u002F\u002F avoid this\n```\n\n### Pure Functions and constexpr\n\n```cpp\n\u002F\u002F F.4 + F.8: Pure, constexpr where possible\nconstexpr int factorial(int n) noexcept {\n    return (n \u003C= 1) ? 1 : n * factorial(n - 1);\n}\n\nstatic_assert(factorial(5) == 120);\n```\n\n### Anti-Patterns\n\n- Returning `T&&` from functions (F.45)\n- Using `va_arg` \u002F C-style variadics (F.55)\n- Capturing by reference in lambdas passed to other threads (F.53)\n- Returning `const T` which inhibits move semantics (F.49)\n\n## Classes & Class Hierarchies (C.*)\n\n### Key Rules\n\n| Rule | Summary |\n|------|---------|\n| **C.2** | Use `class` if invariant exists; `struct` if data members vary independently |\n| **C.9** | Minimize exposure of members |\n| **C.20** | If you can avoid defining default operations, do (Rule of Zero) |\n| **C.21** | If you define or `=delete` any copy\u002Fmove\u002Fdestructor, handle them all (Rule of Five) |\n| **C.35** | Base class destructor: public virtual or protected non-virtual |\n| **C.41** | A constructor should create a fully initialized object |\n| **C.46** | Declare single-argument constructors `explicit` |\n| **C.67** | A polymorphic class should suppress public copy\u002Fmove |\n| **C.128** | Virtual functions: specify exactly one of `virtual`, `override`, or `final` |\n\n### Rule of Zero\n\n```cpp\n\u002F\u002F C.20: Let the compiler generate special members\nstruct Employee {\n    std::string name;\n    std::string department;\n    int id;\n    \u002F\u002F No destructor, copy\u002Fmove constructors, or assignment operators needed\n};\n```\n\n### Rule of Five\n\n```cpp\n\u002F\u002F C.21: If you must manage a resource, define all five\nclass Buffer {\npublic:\n    explicit Buffer(std::size_t size)\n        : data_(std::make_unique\u003Cchar[]>(size)), size_(size) {}\n\n    ~Buffer() = default;\n\n    Buffer(const Buffer& other)\n        : data_(std::make_unique\u003Cchar[]>(other.size_)), size_(other.size_) {\n        std::copy_n(other.data_.get(), size_, data_.get());\n    }\n\n    Buffer& operator=(const Buffer& other) {\n        if (this != &other) {\n            auto new_data = std::make_unique\u003Cchar[]>(other.size_);\n            std::copy_n(other.data_.get(), other.size_, new_data.get());\n            data_ = std::move(new_data);\n            size_ = other.size_;\n        }\n        return *this;\n    }\n\n    Buffer(Buffer&&) noexcept = default;\n    Buffer& operator=(Buffer&&) noexcept = default;\n\nprivate:\n    std::unique_ptr\u003Cchar[]> data_;\n    std::size_t size_;\n};\n```\n\n### Class Hierarchy\n\n```cpp\n\u002F\u002F C.35 + C.128: Virtual destructor, use override\nclass Shape {\npublic:\n    virtual ~Shape() = default;\n    virtual double area() const = 0;  \u002F\u002F C.121: pure interface\n};\n\nclass Circle : public Shape {\npublic:\n    explicit Circle(double r) : radius_(r) {}\n    double area() const override { return 3.14159 * radius_ * radius_; }\n\nprivate:\n    double radius_;\n};\n```\n\n### Anti-Patterns\n\n- Calling virtual functions in constructors\u002Fdestructors (C.82)\n- Using `memset`\u002F`memcpy` on non-trivial types (C.90)\n- Providing different default arguments for virtual function and overrider (C.140)\n- Making data members `const` or references, which suppresses move\u002Fcopy (C.12)\n\n## Resource Management (R.*)\n\n### Key Rules\n\n| Rule | Summary |\n|------|---------|\n| **R.1** | Manage resources automatically using RAII |\n| **R.3** | A raw pointer (`T*`) is non-owning |\n| **R.5** | Prefer scoped objects; don't heap-allocate unnecessarily |\n| **R.10** | Avoid `malloc()`\u002F`free()` |\n| **R.11** | Avoid calling `new` and `delete` explicitly |\n| **R.20** | Use `unique_ptr` or `shared_ptr` to represent ownership |\n| **R.21** | Prefer `unique_ptr` over `shared_ptr` unless sharing ownership |\n| **R.22** | Use `make_shared()` to make `shared_ptr`s |\n\n### Smart Pointer Usage\n\n```cpp\n\u002F\u002F R.11 + R.20 + R.21: RAII with smart pointers\nauto widget = std::make_unique\u003CWidget>(\"config\");  \u002F\u002F unique ownership\nauto cache  = std::make_shared\u003CCache>(1024);        \u002F\u002F shared ownership\n\n\u002F\u002F R.3: Raw pointer = non-owning observer\nvoid render(const Widget* w) {  \u002F\u002F does NOT own w\n    if (w) w->draw();\n}\n\nrender(widget.get());\n```\n\n### RAII Pattern\n\n```cpp\n\u002F\u002F R.1: Resource acquisition is initialization\nclass FileHandle {\npublic:\n    explicit FileHandle(const std::string& path)\n        : handle_(std::fopen(path.c_str(), \"r\")) {\n        if (!handle_) throw std::runtime_error(\"Failed to open: \" + path);\n    }\n\n    ~FileHandle() {\n        if (handle_) std::fclose(handle_);\n    }\n\n    FileHandle(const FileHandle&) = delete;\n    FileHandle& operator=(const FileHandle&) = delete;\n    FileHandle(FileHandle&& other) noexcept\n        : handle_(std::exchange(other.handle_, nullptr)) {}\n    FileHandle& operator=(FileHandle&& other) noexcept {\n        if (this != &other) {\n            if (handle_) std::fclose(handle_);\n            handle_ = std::exchange(other.handle_, nullptr);\n        }\n        return *this;\n    }\n\nprivate:\n    std::FILE* handle_;\n};\n```\n\n### Anti-Patterns\n\n- Naked `new`\u002F`delete` (R.11)\n- `malloc()`\u002F`free()` in C++ code (R.10)\n- Multiple resource allocations in a single expression (R.13 -- exception safety hazard)\n- `shared_ptr` where `unique_ptr` suffices (R.21)\n\n## Expressions & Statements (ES.*)\n\n### Key Rules\n\n| Rule | Summary |\n|------|---------|\n| **ES.5** | Keep scopes small |\n| **ES.20** | Always initialize an object |\n| **ES.23** | Prefer `{}` initializer syntax |\n| **ES.25** | Declare objects `const` or `constexpr` unless modification is intended |\n| **ES.28** | Use lambdas for complex initialization of `const` variables |\n| **ES.45** | Avoid magic constants; use symbolic constants |\n| **ES.46** | Avoid narrowing\u002Flossy arithmetic conversions |\n| **ES.47** | Use `nullptr` rather than `0` or `NULL` |\n| **ES.48** | Avoid casts |\n| **ES.50** | Don't cast away `const` |\n\n### Initialization\n\n```cpp\n\u002F\u002F ES.20 + ES.23 + ES.25: Always initialize, prefer {}, default to const\nconst int max_retries{3};\nconst std::string name{\"widget\"};\nconst std::vector\u003Cint> primes{2, 3, 5, 7, 11};\n\n\u002F\u002F ES.28: Lambda for complex const initialization\nconst auto config = [&] {\n    Config c;\n    c.timeout = std::chrono::seconds{30};\n    c.retries = max_retries;\n    c.verbose = debug_mode;\n    return c;\n}();\n```\n\n### Anti-Patterns\n\n- Uninitialized variables (ES.20)\n- Using `0` or `NULL` as pointer (ES.47 -- use `nullptr`)\n- C-style casts (ES.48 -- use `static_cast`, `const_cast`, etc.)\n- Casting away `const` (ES.50)\n- Magic numbers without named constants (ES.45)\n- Mixing signed and unsigned arithmetic (ES.100)\n- Reusing names in nested scopes (ES.12)\n\n## Error Handling (E.*)\n\n### Key Rules\n\n| Rule | Summary |\n|------|---------|\n| **E.1** | Develop an error-handling strategy early in a design |\n| **E.2** | Throw an exception to signal that a function can't perform its assigned task |\n| **E.6** | Use RAII to prevent leaks |\n| **E.12** | Use `noexcept` when throwing is impossible or unacceptable |\n| **E.14** | Use purpose-designed user-defined types as exceptions |\n| **E.15** | Throw by value, catch by reference |\n| **E.16** | Destructors, deallocation, and swap must never fail |\n| **E.17** | Don't try to catch every exception in every function |\n\n### Exception Hierarchy\n\n```cpp\n\u002F\u002F E.14 + E.15: Custom exception types, throw by value, catch by reference\nclass AppError : public std::runtime_error {\npublic:\n    using std::runtime_error::runtime_error;\n};\n\nclass NetworkError : public AppError {\npublic:\n    NetworkError(const std::string& msg, int code)\n        : AppError(msg), status_code(code) {}\n    int status_code;\n};\n\nvoid fetch_data(const std::string& url) {\n    \u002F\u002F E.2: Throw to signal failure\n    throw NetworkError(\"connection refused\", 503);\n}\n\nvoid run() {\n    try {\n        fetch_data(\"https:\u002F\u002Fapi.example.com\");\n    } catch (const NetworkError& e) {\n        log_error(e.what(), e.status_code);\n    } catch (const AppError& e) {\n        log_error(e.what());\n    }\n    \u002F\u002F E.17: Don't catch everything here -- let unexpected errors propagate\n}\n```\n\n### Anti-Patterns\n\n- Throwing built-in types like `int` or string literals (E.14)\n- Catching by value (slicing risk) (E.15)\n- Empty catch blocks that silently swallow errors\n- Using exceptions for flow control (E.3)\n- Error handling based on global state like `errno` (E.28)\n\n## Constants & Immutability (Con.*)\n\n### All Rules\n\n| Rule | Summary |\n|------|---------|\n| **Con.1** | By default, make objects immutable |\n| **Con.2** | By default, make member functions `const` |\n| **Con.3** | By default, pass pointers and references to `const` |\n| **Con.4** | Use `const` for values that don't change after construction |\n| **Con.5** | Use `constexpr` for values computable at compile time |\n\n```cpp\n\u002F\u002F Con.1 through Con.5: Immutability by default\nclass Sensor {\npublic:\n    explicit Sensor(std::string id) : id_(std::move(id)) {}\n\n    \u002F\u002F Con.2: const member functions by default\n    const std::string& id() const { return id_; }\n    double last_reading() const { return reading_; }\n\n    \u002F\u002F Only non-const when mutation is required\n    void record(double value) { reading_ = value; }\n\nprivate:\n    const std::string id_;  \u002F\u002F Con.4: never changes after construction\n    double reading_{0.0};\n};\n\n\u002F\u002F Con.3: Pass by const reference\nvoid display(const Sensor& s) {\n    std::cout \u003C\u003C s.id() \u003C\u003C \": \" \u003C\u003C s.last_reading() \u003C\u003C '\\n';\n}\n\n\u002F\u002F Con.5: Compile-time constants\nconstexpr double PI = 3.14159265358979;\nconstexpr int MAX_SENSORS = 256;\n```\n\n## Concurrency & Parallelism (CP.*)\n\n### Key Rules\n\n| Rule | Summary |\n|------|---------|\n| **CP.2** | Avoid data races |\n| **CP.3** | Minimize explicit sharing of writable data |\n| **CP.4** | Think in terms of tasks, rather than threads |\n| **CP.8** | Don't use `volatile` for synchronization |\n| **CP.20** | Use RAII, never plain `lock()`\u002F`unlock()` |\n| **CP.21** | Use `std::scoped_lock` to acquire multiple mutexes |\n| **CP.22** | Never call unknown code while holding a lock |\n| **CP.42** | Don't wait without a condition |\n| **CP.44** | Remember to name your `lock_guard`s and `unique_lock`s |\n| **CP.100** | Don't use lock-free programming unless you absolutely have to |\n\n### Safe Locking\n\n```cpp\n\u002F\u002F CP.20 + CP.44: RAII locks, always named\nclass ThreadSafeQueue {\npublic:\n    void push(int value) {\n        std::lock_guard\u003Cstd::mutex> lock(mutex_);  \u002F\u002F CP.44: named!\n        queue_.push(value);\n        cv_.notify_one();\n    }\n\n    int pop() {\n        std::unique_lock\u003Cstd::mutex> lock(mutex_);\n        \u002F\u002F CP.42: Always wait with a condition\n        cv_.wait(lock, [this] { return !queue_.empty(); });\n        const int value = queue_.front();\n        queue_.pop();\n        return value;\n    }\n\nprivate:\n    std::mutex mutex_;             \u002F\u002F CP.50: mutex with its data\n    std::condition_variable cv_;\n    std::queue\u003Cint> queue_;\n};\n```\n\n### Multiple Mutexes\n\n```cpp\n\u002F\u002F CP.21: std::scoped_lock for multiple mutexes (deadlock-free)\nvoid transfer(Account& from, Account& to, double amount) {\n    std::scoped_lock lock(from.mutex_, to.mutex_);\n    from.balance_ -= amount;\n    to.balance_ += amount;\n}\n```\n\n### Anti-Patterns\n\n- `volatile` for synchronization (CP.8 -- it's for hardware I\u002FO only)\n- Detaching threads (CP.26 -- lifetime management becomes nearly impossible)\n- Unnamed lock guards: `std::lock_guard\u003Cstd::mutex>(m);` destroys immediately (CP.44)\n- Holding locks while calling callbacks (CP.22 -- deadlock risk)\n- Lock-free programming without deep expertise (CP.100)\n\n## Templates & Generic Programming (T.*)\n\n### Key Rules\n\n| Rule | Summary |\n|------|---------|\n| **T.1** | Use templates to raise the level of abstraction |\n| **T.2** | Use templates to express algorithms for many argument types |\n| **T.10** | Specify concepts for all template arguments |\n| **T.11** | Use standard concepts whenever possible |\n| **T.13** | Prefer shorthand notation for simple concepts |\n| **T.43** | Prefer `using` over `typedef` |\n| **T.120** | Use template metaprogramming only when you really need to |\n| **T.144** | Don't specialize function templates (overload instead) |\n\n### Concepts (C++20)\n\n```cpp\n#include \u003Cconcepts>\n\n\u002F\u002F T.10 + T.11: Constrain templates with standard concepts\ntemplate\u003Cstd::integral T>\nT gcd(T a, T b) {\n    while (b != 0) {\n        a = std::exchange(b, a % b);\n    }\n    return a;\n}\n\n\u002F\u002F T.13: Shorthand concept syntax\nvoid sort(std::ranges::random_access_range auto& range) {\n    std::ranges::sort(range);\n}\n\n\u002F\u002F Custom concept for domain-specific constraints\ntemplate\u003Ctypename T>\nconcept Serializable = requires(const T& t) {\n    { t.serialize() } -> std::convertible_to\u003Cstd::string>;\n};\n\ntemplate\u003CSerializable T>\nvoid save(const T& obj, const std::string& path);\n```\n\n### Anti-Patterns\n\n- Unconstrained templates in visible namespaces (T.47)\n- Specializing function templates instead of overloading (T.144)\n- Template metaprogramming where `constexpr` suffices (T.120)\n- `typedef` instead of `using` (T.43)\n\n## Standard Library (SL.*)\n\n### Key Rules\n\n| Rule | Summary |\n|------|---------|\n| **SL.1** | Use libraries wherever possible |\n| **SL.2** | Prefer the standard library to other libraries |\n| **SL.con.1** | Prefer `std::array` or `std::vector` over C arrays |\n| **SL.con.2** | Prefer `std::vector` by default |\n| **SL.str.1** | Use `std::string` to own character sequences |\n| **SL.str.2** | Use `std::string_view` to refer to character sequences |\n| **SL.io.50** | Avoid `endl` (use `'\\n'` -- `endl` forces a flush) |\n\n```cpp\n\u002F\u002F SL.con.1 + SL.con.2: Prefer vector\u002Farray over C arrays\nconst std::array\u003Cint, 4> fixed_data{1, 2, 3, 4};\nstd::vector\u003Cstd::string> dynamic_data;\n\n\u002F\u002F SL.str.1 + SL.str.2: string owns, string_view observes\nstd::string build_greeting(std::string_view name) {\n    return \"Hello, \" + std::string(name) + \"!\";\n}\n\n\u002F\u002F SL.io.50: Use '\\n' not endl\nstd::cout \u003C\u003C \"result: \" \u003C\u003C value \u003C\u003C '\\n';\n```\n\n## Enumerations (Enum.*)\n\n### Key Rules\n\n| Rule | Summary |\n|------|---------|\n| **Enum.1** | Prefer enumerations over macros |\n| **Enum.3** | Prefer `enum class` over plain `enum` |\n| **Enum.5** | Don't use ALL_CAPS for enumerators |\n| **Enum.6** | Avoid unnamed enumerations |\n\n```cpp\n\u002F\u002F Enum.3 + Enum.5: Scoped enum, no ALL_CAPS\nenum class Color { red, green, blue };\nenum class LogLevel { debug, info, warning, error };\n\n\u002F\u002F BAD: plain enum leaks names, ALL_CAPS clashes with macros\nenum { RED, GREEN, BLUE };           \u002F\u002F Enum.3 + Enum.5 + Enum.6 violation\n#define MAX_SIZE 100                  \u002F\u002F Enum.1 violation -- use constexpr\n```\n\n## Source Files & Naming (SF.*, NL.*)\n\n### Key Rules\n\n| Rule | Summary |\n|------|---------|\n| **SF.1** | Use `.cpp` for code files and `.h` for interface files |\n| **SF.7** | Don't write `using namespace` at global scope in a header |\n| **SF.8** | Use `#include` guards for all `.h` files |\n| **SF.11** | Header files should be self-contained |\n| **NL.5** | Avoid encoding type information in names (no Hungarian notation) |\n| **NL.8** | Use a consistent naming style |\n| **NL.9** | Use ALL_CAPS for macro names only |\n| **NL.10** | Prefer `underscore_style` names |\n\n### Header Guard\n\n```cpp\n\u002F\u002F SF.8: Include guard (or #pragma once)\n#ifndef PROJECT_MODULE_WIDGET_H\n#define PROJECT_MODULE_WIDGET_H\n\n\u002F\u002F SF.11: Self-contained -- include everything this header needs\n#include \u003Cstring>\n#include \u003Cvector>\n\nnamespace project::module {\n\nclass Widget {\npublic:\n    explicit Widget(std::string name);\n    const std::string& name() const;\n\nprivate:\n    std::string name_;\n};\n\n}  \u002F\u002F namespace project::module\n\n#endif  \u002F\u002F PROJECT_MODULE_WIDGET_H\n```\n\n### Naming Conventions\n\n```cpp\n\u002F\u002F NL.8 + NL.10: Consistent underscore_style\nnamespace my_project {\n\nconstexpr int max_buffer_size = 4096;  \u002F\u002F NL.9: not ALL_CAPS (it's not a macro)\n\nclass tcp_connection {                 \u002F\u002F underscore_style class\npublic:\n    void send_message(std::string_view msg);\n    bool is_connected() const;\n\nprivate:\n    std::string host_;                 \u002F\u002F trailing underscore for members\n    int port_;\n};\n\n}  \u002F\u002F namespace my_project\n```\n\n### Anti-Patterns\n\n- `using namespace std;` in a header at global scope (SF.7)\n- Headers that depend on inclusion order (SF.10, SF.11)\n- Hungarian notation like `strName`, `iCount` (NL.5)\n- ALL_CAPS for anything other than macros (NL.9)\n\n## Performance (Per.*)\n\n### Key Rules\n\n| Rule | Summary |\n|------|---------|\n| **Per.1** | Don't optimize without reason |\n| **Per.2** | Don't optimize prematurely |\n| **Per.6** | Don't make claims about performance without measurements |\n| **Per.7** | Design to enable optimization |\n| **Per.10** | Rely on the static type system |\n| **Per.11** | Move computation from run time to compile time |\n| **Per.19** | Access memory predictably |\n\n### Guidelines\n\n```cpp\n\u002F\u002F Per.11: Compile-time computation where possible\nconstexpr auto lookup_table = [] {\n    std::array\u003Cint, 256> table{};\n    for (int i = 0; i \u003C 256; ++i) {\n        table[i] = i * i;\n    }\n    return table;\n}();\n\n\u002F\u002F Per.19: Prefer contiguous data for cache-friendliness\nstd::vector\u003CPoint> points;           \u002F\u002F GOOD: contiguous\nstd::vector\u003Cstd::unique_ptr\u003CPoint>> indirect_points; \u002F\u002F BAD: pointer chasing\n```\n\n### Anti-Patterns\n\n- Optimizing without profiling data (Per.1, Per.6)\n- Choosing \"clever\" low-level code over clear abstractions (Per.4, Per.5)\n- Ignoring data layout and cache behavior (Per.19)\n\n## Quick Reference Checklist\n\nBefore marking C++ work complete:\n\n- [ ] No raw `new`\u002F`delete` -- use smart pointers or RAII (R.11)\n- [ ] Objects initialized at declaration (ES.20)\n- [ ] Variables are `const`\u002F`constexpr` by default (Con.1, ES.25)\n- [ ] Member functions are `const` where possible (Con.2)\n- [ ] `enum class` instead of plain `enum` (Enum.3)\n- [ ] `nullptr` instead of `0`\u002F`NULL` (ES.47)\n- [ ] No narrowing conversions (ES.46)\n- [ ] No C-style casts (ES.48)\n- [ ] Single-argument constructors are `explicit` (C.46)\n- [ ] Rule of Zero or Rule of Five applied (C.20, C.21)\n- [ ] Base class destructors are public virtual or protected non-virtual (C.35)\n- [ ] Templates are constrained with concepts (T.10)\n- [ ] No `using namespace` in headers at global scope (SF.7)\n- [ ] Headers have include guards and are self-contained (SF.8, SF.11)\n- [ ] Locks use RAII (`scoped_lock`\u002F`lock_guard`) (CP.20)\n- [ ] Exceptions are custom types, thrown by value, caught by reference (E.14, E.15)\n- [ ] `'\\n'` instead of `std::endl` (SL.io.50)\n- [ ] No magic numbers (ES.45)\n","# C++ Coding Standards (C++ Core Guidelines)\n\nComprehensive coding standards for modern C++ (C++17\u002F20\u002F23) derived from the [C++ Core Guidelines](https:\u002F\u002Fisocpp.github.io\u002FCppCoreGuidelines\u002FCppCoreGuidelines). Enforces type safety, resource safety, immutability, and clarity.\n\n## When to Use\n\n- Writing new C++ code (classes, functions, templates)\n- Reviewing or refactoring existing C++ code\n- Making architectural decisions in C++ projects\n- Enforcing consistent style across a C++ codebase\n- Choosing between language features (e.g., `enum` vs `enum class`, raw pointer vs smart pointer)\n\n### When NOT to Use\n\n- Non-C++ projects\n- Legacy C codebases that cannot adopt modern C++ features\n- Embedded\u002Fbare-metal contexts where specific guidelines conflict with hardware constraints (adapt selectively)\n\n## Cross-Cutting Principles\n\nThese themes recur across the entire guidelines and form the foundation:\n\n1. **RAII everywhere** (P.8, R.1, E.6, CP.20): Bind resource lifetime to object lifetime\n2. **Immutability by default** (P.10, Con.1-5, ES.25): Start with `const`\u002F`constexpr`; mutability is the exception\n3. **Type safety** (P.4, I.4, ES.46-49, Enum.3): Use the type system to prevent errors at compile time\n4. **Express intent** (P.3, F.1, NL.1-2, T.10): Names, types, and concepts should communicate purpose\n5. **Minimize complexity** (F.2-3, ES.5, Per.4-5): Simple code is correct code\n6. **Value semantics over pointer semantics** (C.10, R.3-5, F.20, CP.31): Prefer returning by value and scoped objects\n\n## Philosophy & Interfaces (P.*, I.*)\n\n### Key Rules\n\n| Rule | Summary |\n|------|---------|\n| **P.1** | Express ideas directly in code |\n| **P.3** | Express intent |\n| **P.4** | Ideally, a program should be statically type safe |\n| **P.5** | Prefer compile-time checking to run-time checking |\n| **P.8** | Don't leak any resources |\n| **P.10** | Prefer immutable data to mutable data |\n| **I.1** | Make interfaces explicit |\n| **I.2** | Avoid non-const global variables |\n| **I.4** | Make interfaces precisely and strongly typed |\n| **I.11** | Never transfer ownership by a raw pointer or reference |\n| **I.23** | Keep the number of function arguments low |\n\n### DO\n\n```cpp\n\u002F\u002F P.10 + I.4: Immutable, strongly typed interface\nstruct Temperature {\n    double kelvin;\n};\n\nTemperature boil(const Temperature& water);\n```\n\n### DON'T\n\n```cpp\n\u002F\u002F Weak interface: unclear ownership, unclear units\ndouble boil(double* temp);\n\n\u002F\u002F Non-const global variable\nint g_counter = 0;  \u002F\u002F I.2 violation\n```\n\n## Functions (F.*)\n\n### Key Rules\n\n| Rule | Summary |\n|------|---------|\n| **F.1** | Package meaningful operations as carefully named functions |\n| **F.2** | A function should perform a single logical operation |\n| **F.3** | Keep functions short and simple |\n| **F.4** | If a function might be evaluated at compile time, declare it `constexpr` |\n| **F.6** | If your function must not throw, declare it `noexcept` |\n| **F.8** | Prefer pure functions |\n| **F.16** | For \"in\" parameters, pass cheaply-copied types by value and others by `const&` |\n| **F.20** | For \"out\" values, prefer return values to output parameters |\n| **F.21** | To return multiple \"out\" values, prefer returning a struct |\n| **F.43** | Never return a pointer or reference to a local object |\n\n### Parameter Passing\n\n```cpp\n\u002F\u002F F.16: Cheap types by value, others by const&\nvoid print(int x);                           \u002F\u002F cheap: by value\nvoid analyze(const std::string& data);       \u002F\u002F expensive: by const&\nvoid transform(std::string s);               \u002F\u002F sink: by value (will move)\n\n\u002F\u002F F.20 + F.21: Return values, not output parameters\nstruct ParseResult {\n    std::string token;\n    int position;\n};\n\nParseResult parse(std::string_view input);   \u002F\u002F GOOD: return struct\n\n\u002F\u002F BAD: output parameters\nvoid parse(std::string_view input,\n           std::string& token, int& pos);    \u002F\u002F avoid this\n```\n\n### Pure Functions and constexpr\n\n```cpp\n\u002F\u002F F.4 + F.8: Pure, constexpr where possible\nconstexpr int factorial(int n) noexcept {\n    return (n \u003C= 1) ? 1 : n * factorial(n - 1);\n}\n\nstatic_assert(factorial(5) == 120);\n```\n\n### Anti-Patterns\n\n- Returning `T&&` from functions (F.45)\n- Using `va_arg` \u002F C-style variadics (F.55)\n- Capturing by reference in lambdas passed to other threads (F.53)\n- Returning `const T` which inhibits move semantics (F.49)\n\n## Classes & Class Hierarchies (C.*)\n\n### Key Rules\n\n| Rule | Summary |\n|------|---------|\n| **C.2** | Use `class` if invariant exists; `struct` if data members vary independently |\n| **C.9** | Minimize exposure of members |\n| **C.20** | If you can avoid defining default operations, do (Rule of Zero) |\n| **C.21** | If you define or `=delete` any copy\u002Fmove\u002Fdestructor, handle them all (Rule of Five) |\n| **C.35** | Base class destructor: public virtual or protected non-virtual |\n| **C.41** | A constructor should create a fully initialized object |\n| **C.46** | Declare single-argument constructors `explicit` |\n| **C.67** | A polymorphic class should suppress public copy\u002Fmove |\n| **C.128** | Virtual functions: specify exactly one of `virtual`, `override`, or `final` |\n\n### Rule of Zero\n\n```cpp\n\u002F\u002F C.20: Let the compiler generate special members\nstruct Employee {\n    std::string name;\n    std::string department;\n    int id;\n    \u002F\u002F No destructor, copy\u002Fmove constructors, or assignment operators needed\n};\n```\n\n### Rule of Five\n\n```cpp\n\u002F\u002F C.21: If you must manage a resource, define all five\nclass Buffer {\npublic:\n    explicit Buffer(std::size_t size)\n        : data_(std::make_unique\u003Cchar[]>(size)), size_(size) {}\n\n    ~Buffer() = default;\n\n    Buffer(const Buffer& other)\n        : data_(std::make_unique\u003Cchar[]>(other.size_)), size_(other.size_) {\n        std::copy_n(other.data_.get(), size_, data_.get());\n    }\n\n    Buffer& operator=(const Buffer& other) {\n        if (this != &other) {\n            auto new_data = std::make_unique\u003Cchar[]>(other.size_);\n            std::copy_n(other.data_.get(), other.size_, new_data.get());\n            data_ = std::move(new_data);\n            size_ = other.size_;\n        }\n        return *this;\n    }\n\n    Buffer(Buffer&&) noexcept = default;\n    Buffer& operator=(Buffer&&) noexcept = default;\n\nprivate:\n    std::unique_ptr\u003Cchar[]> data_;\n    std::size_t size_;\n};\n```\n\n### Class Hierarchy\n\n```cpp\n\u002F\u002F C.35 + C.128: Virtual destructor, use override\nclass Shape {\npublic:\n    virtual ~Shape() = default;\n    virtual double area() const = 0;  \u002F\u002F C.121: pure interface\n};\n\nclass Circle : public Shape {\npublic:\n    explicit Circle(double r) : radius_(r) {}\n    double area() const override { return 3.14159 * radius_ * radius_; }\n\nprivate:\n    double radius_;\n};\n```\n\n### Anti-Patterns\n\n- Calling virtual functions in constructors\u002Fdestructors (C.82)\n- Using `memset`\u002F`memcpy` on non-trivial types (C.90)\n- Providing different default arguments for virtual function and overrider (C.140)\n- Making data members `const` or references, which suppresses move\u002Fcopy (C.12)\n\n## Resource Management (R.*)\n\n### Key Rules\n\n| Rule | Summary |\n|------|---------|\n| **R.1** | Manage resources automatically using RAII |\n| **R.3** | A raw pointer (`T*`) is non-owning |\n| **R.5** | Prefer scoped objects; don't heap-allocate unnecessarily |\n| **R.10** | Avoid `malloc()`\u002F`free()` |\n| **R.11** | Avoid calling `new` and `delete` explicitly |\n| **R.20** | Use `unique_ptr` or `shared_ptr` to represent ownership |\n| **R.21** | Prefer `unique_ptr` over `shared_ptr` unless sharing ownership |\n| **R.22** | Use `make_shared()` to make `shared_ptr`s |\n\n### Smart Pointer Usage\n\n```cpp\n\u002F\u002F R.11 + R.20 + R.21: RAII with smart pointers\nauto widget = std::make_unique\u003CWidget>(\"config\");  \u002F\u002F unique ownership\nauto cache  = std::make_shared\u003CCache>(1024);        \u002F\u002F shared ownership\n\n\u002F\u002F R.3: Raw pointer = non-owning observer\nvoid render(const Widget* w) {  \u002F\u002F does NOT own w\n    if (w) w->draw();\n}\n\nrender(widget.get());\n```\n\n### RAII Pattern\n\n```cpp\n\u002F\u002F R.1: Resource acquisition is initialization\nclass FileHandle {\npublic:\n    explicit FileHandle(const std::string& path)\n        : handle_(std::fopen(path.c_str(), \"r\")) {\n        if (!handle_) throw std::runtime_error(\"Failed to open: \" + path);\n    }\n\n    ~FileHandle() {\n        if (handle_) std::fclose(handle_);\n    }\n\n    FileHandle(const FileHandle&) = delete;\n    FileHandle& operator=(const FileHandle&) = delete;\n    FileHandle(FileHandle&& other) noexcept\n        : handle_(std::exchange(other.handle_, nullptr)) {}\n    FileHandle& operator=(FileHandle&& other) noexcept {\n        if (this != &other) {\n            if (handle_) std::fclose(handle_);\n            handle_ = std::exchange(other.handle_, nullptr);\n        }\n        return *this;\n    }\n\nprivate:\n    std::FILE* handle_;\n};\n```\n\n### Anti-Patterns\n\n- Naked `new`\u002F`delete` (R.11)\n- `malloc()`\u002F`free()` in C++ code (R.10)\n- Multiple resource allocations in a single expression (R.13 -- exception safety hazard)\n- `shared_ptr` where `unique_ptr` suffices (R.21)\n\n## Expressions & Statements (ES.*)\n\n### Key Rules\n\n| Rule | Summary |\n|------|---------|\n| **ES.5** | Keep scopes small |\n| **ES.20** | Always initialize an object |\n| **ES.23** | Prefer `{}` initializer syntax |\n| **ES.25** | Declare objects `const` or `constexpr` unless modification is intended |\n| **ES.28** | Use lambdas for complex initialization of `const` variables |\n| **ES.45** | Avoid magic constants; use symbolic constants |\n| **ES.46** | Avoid narrowing\u002Flossy arithmetic conversions |\n| **ES.47** | Use `nullptr` rather than `0` or `NULL` |\n| **ES.48** | Avoid casts |\n| **ES.50** | Don't cast away `const` |\n\n### Initialization\n\n```cpp\n\u002F\u002F ES.20 + ES.23 + ES.25: Always initialize, prefer {}, default to const\nconst int max_retries{3};\nconst std::string name{\"widget\"};\nconst std::vector\u003Cint> primes{2, 3, 5, 7, 11};\n\n\u002F\u002F ES.28: Lambda for complex const initialization\nconst auto config = [&] {\n    Config c;\n    c.timeout = std::chrono::seconds{30};\n    c.retries = max_retries;\n    c.verbose = debug_mode;\n    return c;\n}();\n```\n\n### Anti-Patterns\n\n- Uninitialized variables (ES.20)\n- Using `0` or `NULL` as pointer (ES.47 -- use `nullptr`)\n- C-style casts (ES.48 -- use `static_cast`, `const_cast`, etc.)\n- Casting away `const` (ES.50)\n- Magic numbers without named constants (ES.45)\n- Mixing signed and unsigned arithmetic (ES.100)\n- Reusing names in nested scopes (ES.12)\n\n## Error Handling (E.*)\n\n### Key Rules\n\n| Rule | Summary |\n|------|---------|\n| **E.1** | Develop an error-handling strategy early in a design |\n| **E.2** | Throw an exception to signal that a function can't perform its assigned task |\n| **E.6** | Use RAII to prevent leaks |\n| **E.12** | Use `noexcept` when throwing is impossible or unacceptable |\n| **E.14** | Use purpose-designed user-defined types as exceptions |\n| **E.15** | Throw by value, catch by reference |\n| **E.16** | Destructors, deallocation, and swap must never fail |\n| **E.17** | Don't try to catch every exception in every function |\n\n### Exception Hierarchy\n\n```cpp\n\u002F\u002F E.14 + E.15: Custom exception types, throw by value, catch by reference\nclass AppError : public std::runtime_error {\npublic:\n    using std::runtime_error::runtime_error;\n};\n\nclass NetworkError : public AppError {\npublic:\n    NetworkError(const std::string& msg, int code)\n        : AppError(msg), status_code(code) {}\n    int status_code;\n};\n\nvoid fetch_data(const std::string& url) {\n    \u002F\u002F E.2: Throw to signal failure\n    throw NetworkError(\"connection refused\", 503);\n}\n\nvoid run() {\n    try {\n        fetch_data(\"https:\u002F\u002Fapi.example.com\");\n    } catch (const NetworkError& e) {\n        log_error(e.what(), e.status_code);\n    } catch (const AppError& e) {\n        log_error(e.what());\n    }\n    \u002F\u002F E.17: Don't catch everything here -- let unexpected errors propagate\n}\n```\n\n### Anti-Patterns\n\n- Throwing built-in types like `int` or string literals (E.14)\n- Catching by value (slicing risk) (E.15)\n- Empty catch blocks that silently swallow errors\n- Using exceptions for flow control (E.3)\n- Error handling based on global state like `errno` (E.28)\n\n## Constants & Immutability (Con.*)\n\n### All Rules\n\n| Rule | Summary |\n|------|---------|\n| **Con.1** | By default, make objects immutable |\n| **Con.2** | By default, make member functions `const` |\n| **Con.3** | By default, pass pointers and references to `const` |\n| **Con.4** | Use `const` for values that don't change after construction |\n| **Con.5** | Use `constexpr` for values computable at compile time |\n\n```cpp\n\u002F\u002F Con.1 through Con.5: Immutability by default\nclass Sensor {\npublic:\n    explicit Sensor(std::string id) : id_(std::move(id)) {}\n\n    \u002F\u002F Con.2: const member functions by default\n    const std::string& id() const { return id_; }\n    double last_reading() const { return reading_; }\n\n    \u002F\u002F Only non-const when mutation is required\n    void record(double value) { reading_ = value; }\n\nprivate:\n    const std::string id_;  \u002F\u002F Con.4: never changes after construction\n    double reading_{0.0};\n};\n\n\u002F\u002F Con.3: Pass by const reference\nvoid display(const Sensor& s) {\n    std::cout \u003C\u003C s.id() \u003C\u003C \": \" \u003C\u003C s.last_reading() \u003C\u003C '\\n';\n}\n\n\u002F\u002F Con.5: Compile-time constants\nconstexpr double PI = 3.14159265358979;\nconstexpr int MAX_SENSORS = 256;\n```\n\n## Concurrency & Parallelism (CP.*)\n\n### Key Rules\n\n| Rule | Summary |\n|------|---------|\n| **CP.2** | Avoid data races |\n| **CP.3** | Minimize explicit sharing of writable data |\n| **CP.4** | Think in terms of tasks, rather than threads |\n| **CP.8** | Don't use `volatile` for synchronization |\n| **CP.20** | Use RAII, never plain `lock()`\u002F`unlock()` |\n| **CP.21** | Use `std::scoped_lock` to acquire multiple mutexes |\n| **CP.22** | Never call unknown code while holding a lock |\n| **CP.42** | Don't wait without a condition |\n| **CP.44** | Remember to name your `lock_guard`s and `unique_lock`s |\n| **CP.100** | Don't use lock-free programming unless you absolutely have to |\n\n### Safe Locking\n\n```cpp\n\u002F\u002F CP.20 + CP.44: RAII locks, always named\nclass ThreadSafeQueue {\npublic:\n    void push(int value) {\n        std::lock_guard\u003Cstd::mutex> lock(mutex_);  \u002F\u002F CP.44: named!\n        queue_.push(value);\n        cv_.notify_one();\n    }\n\n    int pop() {\n        std::unique_lock\u003Cstd::mutex> lock(mutex_);\n        \u002F\u002F CP.42: Always wait with a condition\n        cv_.wait(lock, [this] { return !queue_.empty(); });\n        const int value = queue_.front();\n        queue_.pop();\n        return value;\n    }\n\nprivate:\n    std::mutex mutex_;             \u002F\u002F CP.50: mutex with its data\n    std::condition_variable cv_;\n    std::queue\u003Cint> queue_;\n};\n```\n\n### Multiple Mutexes\n\n```cpp\n\u002F\u002F CP.21: std::scoped_lock for multiple mutexes (deadlock-free)\nvoid transfer(Account& from, Account& to, double amount) {\n    std::scoped_lock lock(from.mutex_, to.mutex_);\n    from.balance_ -= amount;\n    to.balance_ += amount;\n}\n```\n\n### Anti-Patterns\n\n- `volatile` for synchronization (CP.8 -- it's for hardware I\u002FO only)\n- Detaching threads (CP.26 -- lifetime management becomes nearly impossible)\n- Unnamed lock guards: `std::lock_guard\u003Cstd::mutex>(m);` destroys immediately (CP.44)\n- Holding locks while calling callbacks (CP.22 -- deadlock risk)\n- Lock-free programming without deep expertise (CP.100)\n\n## Templates & Generic Programming (T.*)\n\n### Key Rules\n\n| Rule | Summary |\n|------|---------|\n| **T.1** | Use templates to raise the level of abstraction |\n| **T.2** | Use templates to express algorithms for many argument types |\n| **T.10** | Specify concepts for all template arguments |\n| **T.11** | Use standard concepts whenever possible |\n| **T.13** | Prefer shorthand notation for simple concepts |\n| **T.43** | Prefer `using` over `typedef` |\n| **T.120** | Use template metaprogramming only when you really need to |\n| **T.144** | Don't specialize function templates (overload instead) |\n\n### Concepts (C++20)\n\n```cpp\n#include \u003Cconcepts>\n\n\u002F\u002F T.10 + T.11: Constrain templates with standard concepts\ntemplate\u003Cstd::integral T>\nT gcd(T a, T b) {\n    while (b != 0) {\n        a = std::exchange(b, a % b);\n    }\n    return a;\n}\n\n\u002F\u002F T.13: Shorthand concept syntax\nvoid sort(std::ranges::random_access_range auto& range) {\n    std::ranges::sort(range);\n}\n\n\u002F\u002F Custom concept for domain-specific constraints\ntemplate\u003Ctypename T>\nconcept Serializable = requires(const T& t) {\n    { t.serialize() } -> std::convertible_to\u003Cstd::string>;\n};\n\ntemplate\u003CSerializable T>\nvoid save(const T& obj, const std::string& path);\n```\n\n### Anti-Patterns\n\n- Unconstrained templates in visible namespaces (T.47)\n- Specializing function templates instead of overloading (T.144)\n- Template metaprogramming where `constexpr` suffices (T.120)\n- `typedef` instead of `using` (T.43)\n\n## Standard Library (SL.*)\n\n### Key Rules\n\n| Rule | Summary |\n|------|---------|\n| **SL.1** | Use libraries wherever possible |\n| **SL.2** | Prefer the standard library to other libraries |\n| **SL.con.1** | Prefer `std::array` or `std::vector` over C arrays |\n| **SL.con.2** | Prefer `std::vector` by default |\n| **SL.str.1** | Use `std::string` to own character sequences |\n| **SL.str.2** | Use `std::string_view` to refer to character sequences |\n| **SL.io.50** | Avoid `endl` (use `'\\n'` -- `endl` forces a flush) |\n\n```cpp\n\u002F\u002F SL.con.1 + SL.con.2: Prefer vector\u002Farray over C arrays\nconst std::array\u003Cint, 4> fixed_data{1, 2, 3, 4};\nstd::vector\u003Cstd::string> dynamic_data;\n\n\u002F\u002F SL.str.1 + SL.str.2: string owns, string_view observes\nstd::string build_greeting(std::string_view name) {\n    return \"Hello, \" + std::string(name) + \"!\";\n}\n\n\u002F\u002F SL.io.50: Use '\\n' not endl\nstd::cout \u003C\u003C \"result: \" \u003C\u003C value \u003C\u003C '\\n';\n```\n\n## Enumerations (Enum.*)\n\n### Key Rules\n\n| Rule | Summary |\n|------|---------|\n| **Enum.1** | Prefer enumerations over macros |\n| **Enum.3** | Prefer `enum class` over plain `enum` |\n| **Enum.5** | Don't use ALL_CAPS for enumerators |\n| **Enum.6** | Avoid unnamed enumerations |\n\n```cpp\n\u002F\u002F Enum.3 + Enum.5: Scoped enum, no ALL_CAPS\nenum class Color { red, green, blue };\nenum class LogLevel { debug, info, warning, error };\n\n\u002F\u002F BAD: plain enum leaks names, ALL_CAPS clashes with macros\nenum { RED, GREEN, BLUE };           \u002F\u002F Enum.3 + Enum.5 + Enum.6 violation\n#define MAX_SIZE 100                  \u002F\u002F Enum.1 violation -- use constexpr\n```\n\n## Source Files & Naming (SF.*, NL.*)\n\n### Key Rules\n\n| Rule | Summary |\n|------|---------|\n| **SF.1** | Use `.cpp` for code files and `.h` for interface files |\n| **SF.7** | Don't write `using namespace` at global scope in a header |\n| **SF.8** | Use `#include` guards for all `.h` files |\n| **SF.11** | Header files should be self-contained |\n| **NL.5** | Avoid encoding type information in names (no Hungarian notation) |\n| **NL.8** | Use a consistent naming style |\n| **NL.9** | Use ALL_CAPS for macro names only |\n| **NL.10** | Prefer `underscore_style` names |\n\n### Header Guard\n\n```cpp\n\u002F\u002F SF.8: Include guard (or #pragma once)\n#ifndef PROJECT_MODULE_WIDGET_H\n#define PROJECT_MODULE_WIDGET_H\n\n\u002F\u002F SF.11: Self-contained -- include everything this header needs\n#include \u003Cstring>\n#include \u003Cvector>\n\nnamespace project::module {\n\nclass Widget {\npublic:\n    explicit Widget(std::string name);\n    const std::string& name() const;\n\nprivate:\n    std::string name_;\n};\n\n}  \u002F\u002F namespace project::module\n\n#endif  \u002F\u002F PROJECT_MODULE_WIDGET_H\n```\n\n### Naming Conventions\n\n```cpp\n\u002F\u002F NL.8 + NL.10: Consistent underscore_style\nnamespace my_project {\n\nconstexpr int max_buffer_size = 4096;  \u002F\u002F NL.9: not ALL_CAPS (it's not a macro)\n\nclass tcp_connection {                 \u002F\u002F underscore_style class\npublic:\n    void send_message(std::string_view msg);\n    bool is_connected() const;\n\nprivate:\n    std::string host_;                 \u002F\u002F trailing underscore for members\n    int port_;\n};\n\n}  \u002F\u002F namespace my_project\n```\n\n### Anti-Patterns\n\n- `using namespace std;` in a header at global scope (SF.7)\n- Headers that depend on inclusion order (SF.10, SF.11)\n- Hungarian notation like `strName`, `iCount` (NL.5)\n- ALL_CAPS for anything other than macros (NL.9)\n\n## Performance (Per.*)\n\n### Key Rules\n\n| Rule | Summary |\n|------|---------|\n| **Per.1** | Don't optimize without reason |\n| **Per.2** | Don't optimize prematurely |\n| **Per.6** | Don't make claims about performance without measurements |\n| **Per.7** | Design to enable optimization |\n| **Per.10** | Rely on the static type system |\n| **Per.11** | Move computation from run time to compile time |\n| **Per.19** | Access memory predictably |\n\n### Guidelines\n\n```cpp\n\u002F\u002F Per.11: Compile-time computation where possible\nconstexpr auto lookup_table = [] {\n    std::array\u003Cint, 256> table{};\n    for (int i = 0; i \u003C 256; ++i) {\n        table[i] = i * i;\n    }\n    return table;\n}();\n\n\u002F\u002F Per.19: Prefer contiguous data for cache-friendliness\nstd::vector\u003CPoint> points;           \u002F\u002F GOOD: contiguous\nstd::vector\u003Cstd::unique_ptr\u003CPoint>> indirect_points; \u002F\u002F BAD: pointer chasing\n```\n\n### Anti-Patterns\n\n- Optimizing without profiling data (Per.1, Per.6)\n- Choosing \"clever\" low-level code over clear abstractions (Per.4, Per.5)\n- Ignoring data layout and cache behavior (Per.19)\n\n## Quick Reference Checklist\n\nBefore marking C++ work complete:\n\n- [ ] No raw `new`\u002F`delete` -- use smart pointers or RAII (R.11)\n- [ ] Objects initialized at declaration (ES.20)\n- [ ] Variables are `const`\u002F`constexpr` by default (Con.1, ES.25)\n- [ ] Member functions are `const` where possible (Con.2)\n- [ ] `enum class` instead of plain `enum` (Enum.3)\n- [ ] `nullptr` instead of `0`\u002F`NULL` (ES.47)\n- [ ] No narrowing conversions (ES.46)\n- [ ] No C-style casts (ES.48)\n- [ ] Single-argument constructors are `explicit` (C.46)\n- [ ] Rule of Zero or Rule of Five applied (C.20, C.21)\n- [ ] Base class destructors are public virtual or protected non-virtual (C.35)\n- [ ] Templates are constrained with concepts (T.10)\n- [ ] No `using namespace` in headers at global scope (SF.7)\n- [ ] Headers have include guards and are self-contained (SF.8, SF.11)\n- [ ] Locks use RAII (`scoped_lock`\u002F`lock_guard`) (CP.20)\n- [ ] Exceptions are custom types, thrown by value, caught by reference (E.14, E.15)\n- [ ] `'\\n'` instead of `std::endl` (SL.io.50)\n- [ ] No magic numbers (ES.45)\n",{"name":5,"tags":49,"tools":52,"source":55,"license":14,"description":7,"source_path":56,"source_commit":57},[50,28,51,36],"engineering","coding-standards",[53,54],"monograph_query","monograph_context","https:\u002F\u002Fgithub.com\u002Faffaan-m\u002FECC","skills\u002Fcpp-coding-standards","bf70150eb2df8070024e5bdf08e4aa08959e2735","main","f7cd4595d0f8959822163e14f9787117765c931a","packages\u002F@monomind\u002Fcli\u002Forg-skills\u002Fcpp-coding-standards",2,"https:\u002F\u002Fgithub.com\u002Fmonoes\u002Fmonomind","https:\u002F\u002Fmonoes.github.io\u002Fmonomind\u002F","https:\u002F\u002Fgithub.com\u002Fmonoes","https:\u002F\u002Fmonoes.me","2026-11-10 01:53:48",{"source":8,"skillName":5,"commands":68,"prompt":78,"zipAvailable":79},[69,72,75],{"tool":70,"command":71},"npx","npx skills add monoes\u002Fmonomind --skill cpp-coding-standards",{"tool":73,"command":74},"bunx","bunx skills add monoes\u002Fmonomind --skill cpp-coding-standards",{"tool":76,"command":77},"pnpm","pnpm dlx skills add monoes\u002Fmonomind --skill cpp-coding-standards","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fmonoes\u002Fmonomind\u002Fblob\u002Fmain\u002Fpackages\u002F@monomind\u002Fcli\u002Forg-skills\u002Fcpp-coding-standards\u002FSKILL.md",true,[81],{"path":82,"resourceType":83,"resourceTypeDesc":84,"sizeBytes":85,"sourceHtmlUrl":15},"LICENSE.txt","LICENSE","许可证",1071,[87,114,143,170,195,222],{"skillNo":88,"name":89,"nameZh":6,"description":90,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":91,"licenseFileUrl":6,"sourceHtmlUrl":92,"categories":93,"keywords":94,"publishedAt":113},"01M71PB3SHWKMNJM6MD65VX8D6","zk-steward","Org role guidance for a ZK steward: engineer zero-knowledge proof systems with circuit design, SNARK vs STARK choice and security review. This is zero-knowledge cryptography, not Zettelkasten note-taking.","Apache-2.0","https:\u002F\u002Fgithub.com\u002Fmonoes\u002Fmonomind\u002Fblob\u002Fmain\u002Fpackages\u002F@monomind\u002Fcli\u002Forg-skills\u002Fzk-steward\u002FSKILL.md",[],[95,96,97,98,99,100,101,102,103,38,104,35,105,106,107,108,109,110,111,112],"zk","zk steward","steward","zero-knowledge","engineer","choice","design","knowledge","impact","snark","monomind","security review","stark","zettelkasten","cryptography","security","org","blockchain","2026-11-10 13:02:02",{"skillNo":115,"name":116,"nameZh":6,"description":117,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":118,"sourceHtmlUrl":119,"categories":120,"keywords":129,"publishedAt":113},"01M71PB18SDG28WBKPKJNB814K","writing-plans","Use when you have a spec or requirements for a multi-step coding task and must write an implementation plan before touching code. Produces bite-sized TDD tasks with exact file paths, code and commands for an engineer with zero context.","https:\u002F\u002Fgithub.com\u002Fmonoes\u002Fmonomind\u002Fblob\u002Fmain\u002Fpackages\u002F@monomind\u002Fcli\u002Forg-skills\u002Fwriting-plans\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fmonoes\u002Fmonomind\u002Fblob\u002Fmain\u002Fpackages\u002F@monomind\u002Fcli\u002Forg-skills\u002Fwriting-plans\u002FSKILL.md",[121,126],{"categoryNo":122,"categoryName":123,"taxonomyType":124,"taxonomyTypeDesc":125},"01JBSEEDCAT000000000000018","写作与文案","SCENARIO","使用场景",{"categoryNo":127,"categoryName":128,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000036","内容创作者",[41,130,131,99,132,133,39,134,38,37,135,136,137,138,139,140,141,25,30,142],"writing plans","plans","superpowers","implementation plan","you","tasks","plan","product","write","commands","paths","suggest","ZeRO",{"skillNo":144,"name":145,"nameZh":6,"description":146,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":91,"licenseFileUrl":147,"sourceHtmlUrl":148,"categories":149,"keywords":153,"publishedAt":113},"01M71PAXFM488X9ARXK0T04TF5","write-spec","Write a feature spec or PRD from a problem statement or feature idea. Use when turning a vague idea or user request into a structured document, scoping a feature with goals and non-goals, defining success metrics and acceptance criteria, or breaking a big ask into a phased spec.","https:\u002F\u002Fgithub.com\u002Fmonoes\u002Fmonomind\u002Fblob\u002Fmain\u002Fpackages\u002F@monomind\u002Fcli\u002Forg-skills\u002Fwrite-spec\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fmonoes\u002Fmonomind\u002Fblob\u002Fmain\u002Fpackages\u002F@monomind\u002Fcli\u002Forg-skills\u002Fwrite-spec\u002FSKILL.md",[150],{"categoryNo":151,"categoryName":152,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000031","产品经理",[138,154,155,156,157,102,158,39,159,160,161,137,162,163,164,165,166,167,168,169],"write spec","spec","user request","problem","acceptance","ask","vague","work","request","scoping","idea","metrics","feature","problem statement","use","document",{"skillNo":171,"name":172,"nameZh":6,"description":173,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":91,"licenseFileUrl":174,"sourceHtmlUrl":175,"categories":176,"keywords":180,"publishedAt":113},"01M71PASSZY800C0RPEARBS918","write-query","Write optimized SQL for your dialect with best practices. Use when translating a natural-language data need into SQL, building a multi-CTE query with joins and aggregations, optimizing a query against a large partitioned table, or getting dialect-specific syntax for Snowflake, BigQuery, Postgres, etc.","https:\u002F\u002Fgithub.com\u002Fmonoes\u002Fmonomind\u002Fblob\u002Fmain\u002Fpackages\u002F@monomind\u002Fcli\u002Forg-skills\u002Fwrite-query\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002Fmonoes\u002Fmonomind\u002Fblob\u002Fmain\u002Fpackages\u002F@monomind\u002Fcli\u002Forg-skills\u002Fwrite-query\u002FSKILL.md",[177],{"categoryNo":178,"categoryName":179,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000033","数据分析师",[38,138,181,182,183,184,102,168,39,185,186,187,188,161,189,190,191,192,193,194],"write query","postgres","for","snowflake","best practices","natural-language","with","multi","github","sql","https","syntax","plugins","data",{"skillNo":196,"name":197,"nameZh":6,"description":198,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":91,"licenseFileUrl":6,"sourceHtmlUrl":199,"categories":200,"keywords":207,"publishedAt":113},"01M71PAPTX0T3PF6ETFVR96SJJ","workflow-automation","Org role guidance for workflow automation: build and maintain CI\u002FCD definitions in GitHub Actions or equivalent: triggers, jobs, matrices, caching. Covers path filters, dependency caching, parallel jobs, timeouts and fail-fast ordering.","https:\u002F\u002Fgithub.com\u002Fmonoes\u002Fmonomind\u002Fblob\u002Fmain\u002Fpackages\u002F@monomind\u002Fcli\u002Forg-skills\u002Fworkflow-automation\u002FSKILL.md",[201,204],{"categoryNo":202,"categoryName":203,"taxonomyType":124,"taxonomyTypeDesc":125},"01JBSEEDCAT000000000000011","运维与部署",{"categoryNo":205,"categoryName":206,"taxonomyType":124,"taxonomyTypeDesc":125},"01JBSEEDCAT000000000000023","Skill与智能体开发",[208,209,210,211,183,212,213,214,215,103,216,217,218,38,105,189,219,220,221,191],"Workflow Automation","automation","workflow","parallel","actions","ci","triggers","github actions","maintain","filters","caching","build","dependency","devops",{"skillNo":223,"name":224,"nameZh":6,"description":225,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":9,"repositoryNo":12,"starsCount":13,"licenseSpdxId":91,"licenseFileUrl":6,"sourceHtmlUrl":226,"categories":227,"keywords":229,"publishedAt":113},"01M71PAM19Z1XTV9NPCFSE2MY8","workflow-architect","Org role guidance for a workflow architect: map full workflow trees for systems, user journeys and agents, covering every branch and failure. Covers discovering workflows from code, handoff contracts, timeouts, recovery paths and observable state.","https:\u002F\u002Fgithub.com\u002Fmonoes\u002Fmonomind\u002Fblob\u002Fmain\u002Fpackages\u002F@monomind\u002Fcli\u002Forg-skills\u002Fworkflow-architect\u002FSKILL.md",[228],{"categoryNo":205,"categoryName":206,"taxonomyType":124,"taxonomyTypeDesc":125},[210,230,231,232,233,234,235,183,236,237,37,238,239,240,105,189,241,242,191,243],"workflow architect","architect","trees","user journeys","branch","planning","map","workflows","architecture","state","leadership","recovery","operations","systems"]