[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6E1202WNCWDZPHFXJC1NSSY":3,"skill-same:01M6E1202WNCWDZPHFXJC1NSSY":110},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":22,"publishedAt":31,"linkOnly":32,"markdownContent":33,"markdownBody":34,"frontMatter":35,"refName":37,"commitSha":38,"skillDirectory":39,"forksCount":13,"repositoryHtmlUrl":40,"repositoryHomepageUrl":41,"ownerHtmlUrl":42,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":43,"install":44,"resources":57},"01M6E1202WNCWDZPHFXJC1NSSY","cpp-coding-standards",null,"基于C++核心指南（isocpp.github.io）的C++编码标准。在编写、审查或重构C++代码时使用，以强制实施现代、安全和惯用的实践。","7dvq6yrkgs-stack\u002Fplaywright","7dvq6yrkgs-stack","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F251638143?v=4","01M6E061J2AMGWYZ6TK7Y8NM74","01M6E061PQCQJGQMPBERMCFN5G",0,"Apache-2.0","https:\u002F\u002Fgithub.com\u002F7dvq6yrkgs-stack\u002Fplaywright\u002Fblob\u002Fmain\u002Fskills\u002Fcpp-coding-standards\u002FSKILL.md",[17],{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000008","测试与质量","SCENARIO","使用场景",[23,24,25,26,27,28,29,30],"cpp","coding standards","cpp coding standards","coding","standards","github","安全","io","2026-11-10 10:12:30",false,"---\nname: cpp-coding-standards\ndescription: 基于C++核心指南（isocpp.github.io）的C++编码标准。在编写、审查或重构C++代码时使用，以强制实施现代、安全和惯用的实践。\norigin: ECC\n---\n\n# C++ 编码标准（C++ 核心准则）\n\n源自 [C++ 核心准则](https:\u002F\u002Fisocpp.github.io\u002FCppCoreGuidelines\u002FCppCoreGuidelines) 的现代 C++（C++17\u002F20\u002F23）综合编码标准。强制执行类型安全、资源安全、不变性和清晰性。\n\n## 何时使用\n\n* 编写新的 C++ 代码（类、函数、模板）\n* 审查或重构现有的 C++ 代码\n* 在 C++ 项目中做出架构决策\n* 在 C++ 代码库中强制执行一致的风格\n* 在语言特性之间做出选择（例如，`enum` 对比 `enum class`，原始指针对比智能指针）\n\n### 何时不应使用\n\n* 非 C++ 项目\n* 无法采用现代 C++ 特性的遗留 C 代码库\n* 特定准则与硬件限制冲突的嵌入式\u002F裸机环境（选择性适配）\n\n## 贯穿性原则\n\n这些主题在整个准则中反复出现，并构成了基础：\n\n1. **处处使用 RAII** (P.8, R.1, E.6, CP.20)：将资源生命周期绑定到对象生命周期\n2. **默认为不可变性** (P.10, Con.1-5, ES.25)：从 `const`\u002F`constexpr` 开始；可变性是例外\n3. **类型安全** (P.4, I.4, ES.46-49, Enum.3)：使用类型系统在编译时防止错误\n4. **表达意图** (P.3, F.1, NL.1-2, T.10)：名称、类型和概念应传达目的\n5. **最小化复杂性** (F.2-3, ES.5, Per.4-5)：简单的代码就是正确的代码\n6. **值语义优于指针语义** (C.10, R.3-5, F.20, CP.31)：优先按值返回和作用域对象\n\n## 哲学与接口 (P.\\*, I.\\*)\n\n### 关键规则\n\n| 规则 | 摘要 |\n|------|---------|\n| **P.1** | 直接在代码中表达想法 |\n| **P.3** | 表达意图 |\n| **P.4** | 理想情况下，程序应是静态类型安全的 |\n| **P.5** | 优先编译时检查而非运行时检查 |\n| **P.8** | 不要泄漏任何资源 |\n| **P.10** | 优先不可变数据而非可变数据 |\n| **I.1** | 使接口明确 |\n| **I.2** | 避免非 const 全局变量 |\n| **I.4** | 使接口精确且强类型化 |\n| **I.11** | 切勿通过原始指针或引用转移所有权 |\n| **I.23** | 保持函数参数数量少 |\n\n### 应该做\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### 不应该做\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## 函数 (F.\\*)\n\n### 关键规则\n\n| 规则 | 摘要 |\n|------|---------|\n| **F.1** | 将有意义的操作打包为精心命名的函数 |\n| **F.2** | 函数应执行单一逻辑操作 |\n| **F.3** | 保持函数简短简单 |\n| **F.4** | 如果函数可能在编译时求值，则将其声明为 `constexpr` |\n| **F.6** | 如果你的函数绝不能抛出异常，则将其声明为 `noexcept` |\n| **F.8** | 优先纯函数 |\n| **F.16** | 对于 \"输入\" 参数，按值传递廉价可复制类型，其他类型通过 `const&` 传递 |\n| **F.20** | 对于 \"输出\" 值，优先返回值而非输出参数 |\n| **F.21** | 要返回多个 \"输出\" 值，优先返回结构体 |\n| **F.43** | 切勿返回指向局部对象的指针或引用 |\n\n### 参数传递\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### 纯函数和 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### 反模式\n\n* 从函数返回 `T&&` (F.45)\n* 使用 `va_arg` \u002F C 风格可变参数 (F.55)\n* 在传递给其他线程的 lambda 中通过引用捕获 (F.53)\n* 返回 `const T`，这会抑制移动语义 (F.49)\n\n## 类与类层次结构 (C.\\*)\n\n### 关键规则\n\n| 规则 | 摘要 |\n|------|---------|\n| **C.2** | 如果存在不变式，使用 `class`；如果数据成员独立变化，使用 `struct` |\n| **C.9** | 最小化成员的暴露 |\n| **C.20** | 如果你能避免定义默认操作，就这么做（零规则） |\n| **C.21** | 如果你定义或 `=delete` 任何拷贝\u002F移动\u002F析构函数，则处理所有（五规则） |\n| **C.35** | 基类析构函数：公开虚函数或受保护非虚函数 |\n| **C.41** | 构造函数应创建完全初始化的对象 |\n| **C.46** | 将单参数构造函数声明为 `explicit` |\n| **C.67** | 多态类应禁止公开拷贝\u002F移动 |\n| **C.128** | 虚函数：精确指定 `virtual`、`override` 或 `final` 中的一个 |\n\n### 零规则\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### 五规则\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### 类层次结构\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### 反模式\n\n* 在构造函数\u002F析构函数中调用虚函数 (C.82)\n* 在非平凡类型上使用 `memset`\u002F`memcpy` (C.90)\n* 为虚函数和重写函数提供不同的默认参数 (C.140)\n* 将数据成员设为 `const` 或引用，这会抑制移动\u002F拷贝 (C.12)\n\n## 资源管理 (R.\\*)\n\n### 关键规则\n\n| 规则 | 摘要 |\n|------|---------|\n| **R.1** | 使用 RAII 自动管理资源 |\n| **R.3** | 原始指针 (`T*`) 是非拥有的 |\n| **R.5** | 优先作用域对象；不要不必要地在堆上分配 |\n| **R.10** | 避免 `malloc()`\u002F`free()` |\n| **R.11** | 避免显式调用 `new` 和 `delete` |\n| **R.20** | 使用 `unique_ptr` 或 `shared_ptr` 表示所有权 |\n| **R.21** | 除非共享所有权，否则优先 `unique_ptr` 而非 `shared_ptr` |\n| **R.22** | 使用 `make_shared()` 来创建 `shared_ptr` |\n\n### 智能指针使用\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 模式\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### 反模式\n\n* 裸 `new`\u002F`delete` (R.11)\n* C++ 代码中的 `malloc()`\u002F`free()` (R.10)\n* 在单个表达式中进行多次资源分配 (R.13 -- 异常安全风险)\n* 在 `unique_ptr` 足够时使用 `shared_ptr` (R.21)\n\n## 表达式与语句 (ES.\\*)\n\n### 关键规则\n\n| 规则 | 摘要 |\n|------|---------|\n| **ES.5** | 保持作用域小 |\n| **ES.20** | 始终初始化对象 |\n| **ES.23** | 优先 `{}` 初始化语法 |\n| **ES.25** | 除非打算修改，否则将对象声明为 `const` 或 `constexpr` |\n| **ES.28** | 使用 lambda 进行 `const` 变量的复杂初始化 |\n| **ES.45** | 避免魔法常量；使用符号常量 |\n| **ES.46** | 避免有损的算术转换 |\n| **ES.47** | 使用 `nullptr` 而非 `0` 或 `NULL` |\n| **ES.48** | 避免强制类型转换 |\n| **ES.50** | 不要丢弃 `const` |\n\n### 初始化\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### 反模式\n\n* 未初始化的变量 (ES.20)\n* 使用 `0` 或 `NULL` 作为指针 (ES.47 -- 使用 `nullptr`)\n* C 风格强制类型转换 (ES.48 -- 使用 `static_cast`、`const_cast` 等)\n* 丢弃 `const` (ES.50)\n* 没有命名常量的魔法数字 (ES.45)\n* 混合有符号和无符号算术 (ES.100)\n* 在嵌套作用域中重用名称 (ES.12)\n\n## 错误处理 (E.\\*)\n\n### 关键规则\n\n| 规则 | 摘要 |\n|------|---------|\n| **E.1** | 在设计早期制定错误处理策略 |\n| **E.2** | 抛出异常以表示函数无法执行其分配的任务 |\n| **E.6** | 使用 RAII 防止泄漏 |\n| **E.12** | 当抛出异常不可能或不可接受时，使用 `noexcept` |\n| **E.14** | 使用专门设计的用户定义类型作为异常 |\n| **E.15** | 按值抛出，按引用捕获 |\n| **E.16** | 析构函数、释放和 swap 绝不能失败 |\n| **E.17** | 不要试图在每个函数中捕获每个异常 |\n\n### 异常层次结构\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### 反模式\n\n* 抛出内置类型，如 `int` 或字符串字面量 (E.14)\n* 按值捕获（有切片风险） (E.15)\n* 静默吞掉错误的空 catch 块\n* 使用异常进行流程控制 (E.3)\n* 基于全局状态（如 `errno`）的错误处理 (E.28)\n\n## 常量与不可变性 (Con.\\*)\n\n### 所有规则\n\n| 规则 | 摘要 |\n|------|---------|\n| **Con.1** | 默认情况下，使对象不可变 |\n| **Con.2** | 默认情况下，使成员函数为 `const` |\n| **Con.3** | 默认情况下，传递指向 `const` 的指针和引用 |\n| **Con.4** | 对构造后不改变的值使用 `const` |\n| **Con.5** | 对可在编译时计算的值使用 `constexpr` |\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## 并发与并行 (CP.\\*)\n\n### 关键规则\n\n| 规则 | 摘要 |\n|------|---------|\n| **CP.2** | 避免数据竞争 |\n| **CP.3** | 最小化可写数据的显式共享 |\n| **CP.4** | 从任务的角度思考，而非线程 |\n| **CP.8** | 不要使用 `volatile` 进行同步 |\n| **CP.20** | 使用 RAII，切勿使用普通的 `lock()`\u002F`unlock()` |\n| **CP.21** | 使用 `std::scoped_lock` 来获取多个互斥量 |\n| **CP.22** | 持有锁时切勿调用未知代码 |\n| **CP.42** | 不要在没有条件的情况下等待 |\n| **CP.44** | 记得为你的 `lock_guard` 和 `unique_lock` 命名 |\n| **CP.100** | 除非绝对必要，否则不要使用无锁编程 |\n\n### 安全加锁\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### 多个互斥量\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### 反模式\n\n* 使用 `volatile` 进行同步 (CP.8 -- 它仅用于硬件 I\u002FO)\n* 分离线程 (CP.26 -- 生命周期管理变得几乎不可能)\n* 未命名的锁保护：`std::lock_guard\u003Cstd::mutex>(m);` 会立即销毁 (CP.44)\n* 调用回调时持有锁 (CP.22 -- 死锁风险)\n* 没有深厚专业知识就进行无锁编程 (CP.100)\n\n## 模板与泛型编程 (T.\\*)\n\n### 关键规则\n\n| 规则 | 摘要 |\n|------|---------|\n| **T.1** | 使用模板来提高抽象级别 |\n| **T.2** | 使用模板为多种参数类型表达算法 |\n| **T.10** | 为所有模板参数指定概念 |\n| **T.11** | 尽可能使用标准概念 |\n| **T.13** | 对于简单概念，优先使用简写符号 |\n| **T.43** | 优先 `using` 而非 `typedef` |\n| **T.120** | 仅在确实需要时使用模板元编程 |\n| **T.144** | 不要特化函数模板（改用重载） |\n\n### 概念 (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### 反模式\n\n* 在可见命名空间中使用无约束模板 (T.47)\n* 特化函数模板而非重载 (T.144)\n* 在 `constexpr` 足够时使用模板元编程 (T.120)\n* 使用 `typedef` 而非 `using` (T.43)\n\n## 标准库 (SL.\\*)\n\n### 关键规则\n\n| 规则 | 摘要 |\n|------|---------|\n| **SL.1** | 尽可能使用库 |\n| **SL.2** | 优先标准库而非其他库 |\n| **SL.con.1** | 优先 `std::array` 或 `std::vector` 而非 C 数组 |\n| **SL.con.2** | 默认情况下优先 `std::vector` |\n| **SL.str.1** | 使用 `std::string` 来拥有字符序列 |\n| **SL.str.2** | 使用 `std::string_view` 来引用字符序列 |\n| **SL.io.50** | 避免 `endl`（使用 `'\\n'` -- `endl` 会强制刷新） |\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## 枚举 (Enum.\\*)\n\n### 关键规则\n\n| 规则 | 摘要 |\n|------|---------|\n| **Enum.1** | 优先枚举而非宏 |\n| **Enum.3** | 优先 `enum class` 而非普通 `enum` |\n| **Enum.5** | 不要对枚举项使用全大写 |\n| **Enum.6** | 避免未命名的枚举 |\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## 源文件与命名 (SF.*, NL.*)\n\n### 关键规则\n\n| 规则 | 摘要 |\n|------|---------|\n| **SF.1** | 代码文件使用 `.cpp`，接口文件使用 `.h` |\n| **SF.7** | 不要在头文件的全局作用域内写 `using namespace` |\n| **SF.8** | 所有 `.h` 文件都应使用 `#include` 防护 |\n| **SF.11** | 头文件应是自包含的 |\n| **NL.5** | 避免在名称中编码类型信息（不要使用匈牙利命名法） |\n| **NL.8** | 使用一致的命名风格 |\n| **NL.9** | 仅宏名使用 ALL\\_CAPS |\n| **NL.10** | 优先使用 `underscore_style` 命名 |\n\n### 头文件防护\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### 命名约定\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### 反模式\n\n* 在头文件的全局作用域内使用 `using namespace std;` (SF.7)\n* 依赖包含顺序的头文件 (SF.10, SF.11)\n* 匈牙利命名法，如 `strName`、`iCount` (NL.5)\n* 宏以外的事物使用 ALL\\_CAPS (NL.9)\n\n## 性能 (Per.\\*)\n\n### 关键规则\n\n| 规则 | 摘要 |\n|------|---------|\n| **Per.1** | 不要无故优化 |\n| **Per.2** | 不要过早优化 |\n| **Per.6** | 没有测量数据，不要断言性能 |\n| **Per.7** | 设计时应考虑便于优化 |\n| **Per.10** | 依赖静态类型系统 |\n| **Per.11** | 将计算从运行时移至编译时 |\n| **Per.19** | 以可预测的方式访问内存 |\n\n### 指导原则\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### 反模式\n\n* 在没有性能分析数据的情况下进行优化 (Per.1, Per.6)\n* 选择“巧妙”的低级代码而非清晰的抽象 (Per.4, Per.5)\n* 忽略数据布局和缓存行为 (Per.19)\n\n## 快速参考检查清单\n\n在标记 C++ 工作完成之前：\n\n* \\[ ] 没有裸 `new`\u002F`delete` —— 使用智能指针或 RAII (R.11)\n* \\[ ] 对象在声明时初始化 (ES.20)\n* \\[ ] 变量默认是 `const`\u002F`constexpr` (Con.1, ES.25)\n* \\[ ] 成员函数尽可能设为 `const` (Con.2)\n* \\[ ] 使用 `enum class` 而非普通 `enum` (Enum.3)\n* \\[ ] 使用 `nullptr` 而非 `0`\u002F`NULL` (ES.47)\n* \\[ ] 没有窄化转换 (ES.46)\n* \\[ ] 没有 C 风格转换 (ES.48)\n* \\[ ] 单参数构造函数是 `explicit` (C.46)\n* \\[ ] 应用了零法则或五法则 (C.20, C.21)\n* \\[ ] 基类析构函数是 public virtual 或 protected non-virtual (C.35)\n* \\[ ] 模板使用概念进行约束 (T.10)\n* \\[ ] 头文件全局作用域内没有 `using namespace` (SF.7)\n* \\[ ] 头文件有包含防护且是自包含的 (SF.8, SF.11)\n* \\[ ] 锁使用 RAII (`scoped_lock`\u002F`lock_guard`) (CP.20)\n* \\[ ] 异常是自定义类型，按值抛出，按引用捕获 (E.14, E.15)\n* \\[ ] 使用 `'\\n'` 而非 `std::endl` (SL.io.50)\n* \\[ ] 没有魔数 (ES.45)\n","# C++ 编码标准（C++ 核心准则）\n\n源自 [C++ 核心准则](https:\u002F\u002Fisocpp.github.io\u002FCppCoreGuidelines\u002FCppCoreGuidelines) 的现代 C++（C++17\u002F20\u002F23）综合编码标准。强制执行类型安全、资源安全、不变性和清晰性。\n\n## 何时使用\n\n* 编写新的 C++ 代码（类、函数、模板）\n* 审查或重构现有的 C++ 代码\n* 在 C++ 项目中做出架构决策\n* 在 C++ 代码库中强制执行一致的风格\n* 在语言特性之间做出选择（例如，`enum` 对比 `enum class`，原始指针对比智能指针）\n\n### 何时不应使用\n\n* 非 C++ 项目\n* 无法采用现代 C++ 特性的遗留 C 代码库\n* 特定准则与硬件限制冲突的嵌入式\u002F裸机环境（选择性适配）\n\n## 贯穿性原则\n\n这些主题在整个准则中反复出现，并构成了基础：\n\n1. **处处使用 RAII** (P.8, R.1, E.6, CP.20)：将资源生命周期绑定到对象生命周期\n2. **默认为不可变性** (P.10, Con.1-5, ES.25)：从 `const`\u002F`constexpr` 开始；可变性是例外\n3. **类型安全** (P.4, I.4, ES.46-49, Enum.3)：使用类型系统在编译时防止错误\n4. **表达意图** (P.3, F.1, NL.1-2, T.10)：名称、类型和概念应传达目的\n5. **最小化复杂性** (F.2-3, ES.5, Per.4-5)：简单的代码就是正确的代码\n6. **值语义优于指针语义** (C.10, R.3-5, F.20, CP.31)：优先按值返回和作用域对象\n\n## 哲学与接口 (P.\\*, I.\\*)\n\n### 关键规则\n\n| 规则 | 摘要 |\n|------|---------|\n| **P.1** | 直接在代码中表达想法 |\n| **P.3** | 表达意图 |\n| **P.4** | 理想情况下，程序应是静态类型安全的 |\n| **P.5** | 优先编译时检查而非运行时检查 |\n| **P.8** | 不要泄漏任何资源 |\n| **P.10** | 优先不可变数据而非可变数据 |\n| **I.1** | 使接口明确 |\n| **I.2** | 避免非 const 全局变量 |\n| **I.4** | 使接口精确且强类型化 |\n| **I.11** | 切勿通过原始指针或引用转移所有权 |\n| **I.23** | 保持函数参数数量少 |\n\n### 应该做\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### 不应该做\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## 函数 (F.\\*)\n\n### 关键规则\n\n| 规则 | 摘要 |\n|------|---------|\n| **F.1** | 将有意义的操作打包为精心命名的函数 |\n| **F.2** | 函数应执行单一逻辑操作 |\n| **F.3** | 保持函数简短简单 |\n| **F.4** | 如果函数可能在编译时求值，则将其声明为 `constexpr` |\n| **F.6** | 如果你的函数绝不能抛出异常，则将其声明为 `noexcept` |\n| **F.8** | 优先纯函数 |\n| **F.16** | 对于 \"输入\" 参数，按值传递廉价可复制类型，其他类型通过 `const&` 传递 |\n| **F.20** | 对于 \"输出\" 值，优先返回值而非输出参数 |\n| **F.21** | 要返回多个 \"输出\" 值，优先返回结构体 |\n| **F.43** | 切勿返回指向局部对象的指针或引用 |\n\n### 参数传递\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### 纯函数和 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### 反模式\n\n* 从函数返回 `T&&` (F.45)\n* 使用 `va_arg` \u002F C 风格可变参数 (F.55)\n* 在传递给其他线程的 lambda 中通过引用捕获 (F.53)\n* 返回 `const T`，这会抑制移动语义 (F.49)\n\n## 类与类层次结构 (C.\\*)\n\n### 关键规则\n\n| 规则 | 摘要 |\n|------|---------|\n| **C.2** | 如果存在不变式，使用 `class`；如果数据成员独立变化，使用 `struct` |\n| **C.9** | 最小化成员的暴露 |\n| **C.20** | 如果你能避免定义默认操作，就这么做（零规则） |\n| **C.21** | 如果你定义或 `=delete` 任何拷贝\u002F移动\u002F析构函数，则处理所有（五规则） |\n| **C.35** | 基类析构函数：公开虚函数或受保护非虚函数 |\n| **C.41** | 构造函数应创建完全初始化的对象 |\n| **C.46** | 将单参数构造函数声明为 `explicit` |\n| **C.67** | 多态类应禁止公开拷贝\u002F移动 |\n| **C.128** | 虚函数：精确指定 `virtual`、`override` 或 `final` 中的一个 |\n\n### 零规则\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### 五规则\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### 类层次结构\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### 反模式\n\n* 在构造函数\u002F析构函数中调用虚函数 (C.82)\n* 在非平凡类型上使用 `memset`\u002F`memcpy` (C.90)\n* 为虚函数和重写函数提供不同的默认参数 (C.140)\n* 将数据成员设为 `const` 或引用，这会抑制移动\u002F拷贝 (C.12)\n\n## 资源管理 (R.\\*)\n\n### 关键规则\n\n| 规则 | 摘要 |\n|------|---------|\n| **R.1** | 使用 RAII 自动管理资源 |\n| **R.3** | 原始指针 (`T*`) 是非拥有的 |\n| **R.5** | 优先作用域对象；不要不必要地在堆上分配 |\n| **R.10** | 避免 `malloc()`\u002F`free()` |\n| **R.11** | 避免显式调用 `new` 和 `delete` |\n| **R.20** | 使用 `unique_ptr` 或 `shared_ptr` 表示所有权 |\n| **R.21** | 除非共享所有权，否则优先 `unique_ptr` 而非 `shared_ptr` |\n| **R.22** | 使用 `make_shared()` 来创建 `shared_ptr` |\n\n### 智能指针使用\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 模式\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### 反模式\n\n* 裸 `new`\u002F`delete` (R.11)\n* C++ 代码中的 `malloc()`\u002F`free()` (R.10)\n* 在单个表达式中进行多次资源分配 (R.13 -- 异常安全风险)\n* 在 `unique_ptr` 足够时使用 `shared_ptr` (R.21)\n\n## 表达式与语句 (ES.\\*)\n\n### 关键规则\n\n| 规则 | 摘要 |\n|------|---------|\n| **ES.5** | 保持作用域小 |\n| **ES.20** | 始终初始化对象 |\n| **ES.23** | 优先 `{}` 初始化语法 |\n| **ES.25** | 除非打算修改，否则将对象声明为 `const` 或 `constexpr` |\n| **ES.28** | 使用 lambda 进行 `const` 变量的复杂初始化 |\n| **ES.45** | 避免魔法常量；使用符号常量 |\n| **ES.46** | 避免有损的算术转换 |\n| **ES.47** | 使用 `nullptr` 而非 `0` 或 `NULL` |\n| **ES.48** | 避免强制类型转换 |\n| **ES.50** | 不要丢弃 `const` |\n\n### 初始化\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### 反模式\n\n* 未初始化的变量 (ES.20)\n* 使用 `0` 或 `NULL` 作为指针 (ES.47 -- 使用 `nullptr`)\n* C 风格强制类型转换 (ES.48 -- 使用 `static_cast`、`const_cast` 等)\n* 丢弃 `const` (ES.50)\n* 没有命名常量的魔法数字 (ES.45)\n* 混合有符号和无符号算术 (ES.100)\n* 在嵌套作用域中重用名称 (ES.12)\n\n## 错误处理 (E.\\*)\n\n### 关键规则\n\n| 规则 | 摘要 |\n|------|---------|\n| **E.1** | 在设计早期制定错误处理策略 |\n| **E.2** | 抛出异常以表示函数无法执行其分配的任务 |\n| **E.6** | 使用 RAII 防止泄漏 |\n| **E.12** | 当抛出异常不可能或不可接受时，使用 `noexcept` |\n| **E.14** | 使用专门设计的用户定义类型作为异常 |\n| **E.15** | 按值抛出，按引用捕获 |\n| **E.16** | 析构函数、释放和 swap 绝不能失败 |\n| **E.17** | 不要试图在每个函数中捕获每个异常 |\n\n### 异常层次结构\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### 反模式\n\n* 抛出内置类型，如 `int` 或字符串字面量 (E.14)\n* 按值捕获（有切片风险） (E.15)\n* 静默吞掉错误的空 catch 块\n* 使用异常进行流程控制 (E.3)\n* 基于全局状态（如 `errno`）的错误处理 (E.28)\n\n## 常量与不可变性 (Con.\\*)\n\n### 所有规则\n\n| 规则 | 摘要 |\n|------|---------|\n| **Con.1** | 默认情况下，使对象不可变 |\n| **Con.2** | 默认情况下，使成员函数为 `const` |\n| **Con.3** | 默认情况下，传递指向 `const` 的指针和引用 |\n| **Con.4** | 对构造后不改变的值使用 `const` |\n| **Con.5** | 对可在编译时计算的值使用 `constexpr` |\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## 并发与并行 (CP.\\*)\n\n### 关键规则\n\n| 规则 | 摘要 |\n|------|---------|\n| **CP.2** | 避免数据竞争 |\n| **CP.3** | 最小化可写数据的显式共享 |\n| **CP.4** | 从任务的角度思考，而非线程 |\n| **CP.8** | 不要使用 `volatile` 进行同步 |\n| **CP.20** | 使用 RAII，切勿使用普通的 `lock()`\u002F`unlock()` |\n| **CP.21** | 使用 `std::scoped_lock` 来获取多个互斥量 |\n| **CP.22** | 持有锁时切勿调用未知代码 |\n| **CP.42** | 不要在没有条件的情况下等待 |\n| **CP.44** | 记得为你的 `lock_guard` 和 `unique_lock` 命名 |\n| **CP.100** | 除非绝对必要，否则不要使用无锁编程 |\n\n### 安全加锁\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### 多个互斥量\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### 反模式\n\n* 使用 `volatile` 进行同步 (CP.8 -- 它仅用于硬件 I\u002FO)\n* 分离线程 (CP.26 -- 生命周期管理变得几乎不可能)\n* 未命名的锁保护：`std::lock_guard\u003Cstd::mutex>(m);` 会立即销毁 (CP.44)\n* 调用回调时持有锁 (CP.22 -- 死锁风险)\n* 没有深厚专业知识就进行无锁编程 (CP.100)\n\n## 模板与泛型编程 (T.\\*)\n\n### 关键规则\n\n| 规则 | 摘要 |\n|------|---------|\n| **T.1** | 使用模板来提高抽象级别 |\n| **T.2** | 使用模板为多种参数类型表达算法 |\n| **T.10** | 为所有模板参数指定概念 |\n| **T.11** | 尽可能使用标准概念 |\n| **T.13** | 对于简单概念，优先使用简写符号 |\n| **T.43** | 优先 `using` 而非 `typedef` |\n| **T.120** | 仅在确实需要时使用模板元编程 |\n| **T.144** | 不要特化函数模板（改用重载） |\n\n### 概念 (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### 反模式\n\n* 在可见命名空间中使用无约束模板 (T.47)\n* 特化函数模板而非重载 (T.144)\n* 在 `constexpr` 足够时使用模板元编程 (T.120)\n* 使用 `typedef` 而非 `using` (T.43)\n\n## 标准库 (SL.\\*)\n\n### 关键规则\n\n| 规则 | 摘要 |\n|------|---------|\n| **SL.1** | 尽可能使用库 |\n| **SL.2** | 优先标准库而非其他库 |\n| **SL.con.1** | 优先 `std::array` 或 `std::vector` 而非 C 数组 |\n| **SL.con.2** | 默认情况下优先 `std::vector` |\n| **SL.str.1** | 使用 `std::string` 来拥有字符序列 |\n| **SL.str.2** | 使用 `std::string_view` 来引用字符序列 |\n| **SL.io.50** | 避免 `endl`（使用 `'\\n'` -- `endl` 会强制刷新） |\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## 枚举 (Enum.\\*)\n\n### 关键规则\n\n| 规则 | 摘要 |\n|------|---------|\n| **Enum.1** | 优先枚举而非宏 |\n| **Enum.3** | 优先 `enum class` 而非普通 `enum` |\n| **Enum.5** | 不要对枚举项使用全大写 |\n| **Enum.6** | 避免未命名的枚举 |\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## 源文件与命名 (SF.*, NL.*)\n\n### 关键规则\n\n| 规则 | 摘要 |\n|------|---------|\n| **SF.1** | 代码文件使用 `.cpp`，接口文件使用 `.h` |\n| **SF.7** | 不要在头文件的全局作用域内写 `using namespace` |\n| **SF.8** | 所有 `.h` 文件都应使用 `#include` 防护 |\n| **SF.11** | 头文件应是自包含的 |\n| **NL.5** | 避免在名称中编码类型信息（不要使用匈牙利命名法） |\n| **NL.8** | 使用一致的命名风格 |\n| **NL.9** | 仅宏名使用 ALL\\_CAPS |\n| **NL.10** | 优先使用 `underscore_style` 命名 |\n\n### 头文件防护\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### 命名约定\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### 反模式\n\n* 在头文件的全局作用域内使用 `using namespace std;` (SF.7)\n* 依赖包含顺序的头文件 (SF.10, SF.11)\n* 匈牙利命名法，如 `strName`、`iCount` (NL.5)\n* 宏以外的事物使用 ALL\\_CAPS (NL.9)\n\n## 性能 (Per.\\*)\n\n### 关键规则\n\n| 规则 | 摘要 |\n|------|---------|\n| **Per.1** | 不要无故优化 |\n| **Per.2** | 不要过早优化 |\n| **Per.6** | 没有测量数据，不要断言性能 |\n| **Per.7** | 设计时应考虑便于优化 |\n| **Per.10** | 依赖静态类型系统 |\n| **Per.11** | 将计算从运行时移至编译时 |\n| **Per.19** | 以可预测的方式访问内存 |\n\n### 指导原则\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### 反模式\n\n* 在没有性能分析数据的情况下进行优化 (Per.1, Per.6)\n* 选择“巧妙”的低级代码而非清晰的抽象 (Per.4, Per.5)\n* 忽略数据布局和缓存行为 (Per.19)\n\n## 快速参考检查清单\n\n在标记 C++ 工作完成之前：\n\n* \\[ ] 没有裸 `new`\u002F`delete` —— 使用智能指针或 RAII (R.11)\n* \\[ ] 对象在声明时初始化 (ES.20)\n* \\[ ] 变量默认是 `const`\u002F`constexpr` (Con.1, ES.25)\n* \\[ ] 成员函数尽可能设为 `const` (Con.2)\n* \\[ ] 使用 `enum class` 而非普通 `enum` (Enum.3)\n* \\[ ] 使用 `nullptr` 而非 `0`\u002F`NULL` (ES.47)\n* \\[ ] 没有窄化转换 (ES.46)\n* \\[ ] 没有 C 风格转换 (ES.48)\n* \\[ ] 单参数构造函数是 `explicit` (C.46)\n* \\[ ] 应用了零法则或五法则 (C.20, C.21)\n* \\[ ] 基类析构函数是 public virtual 或 protected non-virtual (C.35)\n* \\[ ] 模板使用概念进行约束 (T.10)\n* \\[ ] 头文件全局作用域内没有 `using namespace` (SF.7)\n* \\[ ] 头文件有包含防护且是自包含的 (SF.8, SF.11)\n* \\[ ] 锁使用 RAII (`scoped_lock`\u002F`lock_guard`) (CP.20)\n* \\[ ] 异常是自定义类型，按值抛出，按引用捕获 (E.14, E.15)\n* \\[ ] 使用 `'\\n'` 而非 `std::endl` (SL.io.50)\n* \\[ ] 没有魔数 (ES.45)\n",{"name":5,"origin":36,"description":7},"ECC","main","a2e3284ed4488780397ee2f78217366e11470dfb","skills\u002Fcpp-coding-standards","https:\u002F\u002Fgithub.com\u002F7dvq6yrkgs-stack\u002Fplaywright","https:\u002F\u002Fplaywright.dev","https:\u002F\u002Fgithub.com\u002F7dvq6yrkgs-stack","2026-04-25 06:04:45",{"source":8,"skillName":5,"commands":45,"prompt":55,"zipAvailable":56},[46,49,52],{"tool":47,"command":48},"npx","npx skills add 7dvq6yrkgs-stack\u002Fplaywright --skill cpp-coding-standards",{"tool":50,"command":51},"bunx","bunx skills add 7dvq6yrkgs-stack\u002Fplaywright --skill cpp-coding-standards",{"tool":53,"command":54},"pnpm","pnpm dlx skills add 7dvq6yrkgs-stack\u002Fplaywright --skill cpp-coding-standards","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002F7dvq6yrkgs-stack\u002Fplaywright\u002Fblob\u002Fmain\u002Fskills\u002Fcpp-coding-standards\u002FSKILL.md",true,[58,64,68,72,76,80,84,88,92,96,100,104],{"path":59,"resourceType":60,"resourceTypeDesc":61,"sizeBytes":62,"sourceHtmlUrl":63},".skillfish.json","REFERENCE","参考文档",258,"https:\u002F\u002Fgithub.com\u002F7dvq6yrkgs-stack\u002Fplaywright\u002Fblob\u002Fmain\u002Fskills\u002Fcpp-coding-standards\u002F.skillfish.json",{"path":65,"resourceType":60,"resourceTypeDesc":61,"sizeBytes":66,"sourceHtmlUrl":67},"agents\u002FSentinelCryptoWeb3\u002FAGENT.md",2596,"https:\u002F\u002Fgithub.com\u002FiDorgham\u002FWorkspace-Factory\u002Fblob\u002Fmaster\u002Ffactory\u002Flibrary\u002Farchive\u002Flegacy_pillars\u002F40_verticals\u002F11_industry_verticals\u002Fcrypto_web3\u002Fagents\u002FSentinelCryptoWeb3\u002FAGENT.md",{"path":69,"resourceType":60,"resourceTypeDesc":61,"sizeBytes":70,"sourceHtmlUrl":71},"agents\u002FWeb3Architect\u002FAGENT.md",2868,"https:\u002F\u002Fgithub.com\u002FiDorgham\u002FWorkspace-Factory\u002Fblob\u002Fmaster\u002Ffactory\u002Flibrary\u002Farchive\u002Flegacy_pillars\u002F40_verticals\u002F11_industry_verticals\u002Fcrypto_web3\u002Fagents\u002FWeb3Architect\u002FAGENT.md",{"path":73,"resourceType":60,"resourceTypeDesc":61,"sizeBytes":74,"sourceHtmlUrl":75},"commands\u002FCOMMANDS.md",3158,"https:\u002F\u002Fgithub.com\u002FiDorgham\u002FWorkspace-Factory\u002Fblob\u002Fmaster\u002Ffactory\u002Flibrary\u002Farchive\u002Flegacy_pillars\u002F40_verticals\u002F11_industry_verticals\u002Fcrypto_web3\u002Fcommands\u002FCOMMANDS.md",{"path":77,"resourceType":60,"resourceTypeDesc":61,"sizeBytes":78,"sourceHtmlUrl":79},"commands\u002FREADME.md",2311,"https:\u002F\u002Fgithub.com\u002FiDorgham\u002FWorkspace-Factory\u002Fblob\u002Fmaster\u002Ffactory\u002Flibrary\u002Farchive\u002Flegacy_pillars\u002F40_verticals\u002F11_industry_verticals\u002Fcrypto_web3\u002Fcommands\u002FREADME.md",{"path":81,"resourceType":60,"resourceTypeDesc":61,"sizeBytes":82,"sourceHtmlUrl":83},"README.md",3350,"https:\u002F\u002Fgithub.com\u002FiDorgham\u002FWorkspace-Factory\u002Fblob\u002Fmaster\u002Ffactory\u002Flibrary\u002Farchive\u002Flegacy_pillars\u002F40_verticals\u002F11_industry_verticals\u002Fcrypto_web3\u002FREADME.md",{"path":85,"resourceType":60,"resourceTypeDesc":61,"sizeBytes":86,"sourceHtmlUrl":87},"subagents\u002Fdefi-protocol-analyzer.json",377,"https:\u002F\u002Fgithub.com\u002FiDorgham\u002FWorkspace-Factory\u002Fblob\u002Fmaster\u002Ffactory\u002Flibrary\u002Farchive\u002Flegacy_pillars\u002F40_verticals\u002F11_industry_verticals\u002Fcrypto_web3\u002Fsubagents\u002Fdefi-protocol-analyzer.json",{"path":89,"resourceType":60,"resourceTypeDesc":61,"sizeBytes":90,"sourceHtmlUrl":91},"subagents\u002Fsolidity-auditor.json",350,"https:\u002F\u002Fgithub.com\u002FiDorgham\u002FWorkspace-Factory\u002Fblob\u002Fmaster\u002Ffactory\u002Flibrary\u002Farchive\u002Flegacy_pillars\u002F40_verticals\u002F11_industry_verticals\u002Fcrypto_web3\u002Fsubagents\u002Fsolidity-auditor.json",{"path":93,"resourceType":60,"resourceTypeDesc":61,"sizeBytes":94,"sourceHtmlUrl":95},"subagents\u002Ftokenomics-modeler.json",360,"https:\u002F\u002Fgithub.com\u002FiDorgham\u002FWorkspace-Factory\u002Fblob\u002Fmaster\u002Ffactory\u002Flibrary\u002Farchive\u002Flegacy_pillars\u002F40_verticals\u002F11_industry_verticals\u002Fcrypto_web3\u002Fsubagents\u002Ftokenomics-modeler.json",{"path":97,"resourceType":60,"resourceTypeDesc":61,"sizeBytes":98,"sourceHtmlUrl":99},"templates\u002FPLAN_BLUEPRINT.md",2955,"https:\u002F\u002Fgithub.com\u002FiDorgham\u002FWorkspace-Factory\u002Fblob\u002Fmaster\u002Ffactory\u002Flibrary\u002Farchive\u002Flegacy_pillars\u002F40_verticals\u002F11_industry_verticals\u002Fcrypto_web3\u002Ftemplates\u002FPLAN_BLUEPRINT.md",{"path":101,"resourceType":60,"resourceTypeDesc":61,"sizeBytes":102,"sourceHtmlUrl":103},"templates\u002FREADME.md",2754,"https:\u002F\u002Fgithub.com\u002FiDorgham\u002FWorkspace-Factory\u002Fblob\u002Fmaster\u002Ffactory\u002Flibrary\u002Farchive\u002Flegacy_pillars\u002F40_verticals\u002F11_industry_verticals\u002Fcrypto_web3\u002Ftemplates\u002FREADME.md",{"path":105,"resourceType":106,"resourceTypeDesc":107,"sizeBytes":108,"sourceHtmlUrl":109},"tests\u002Ftest_core.py","SCRIPT","脚本",175,"https:\u002F\u002Fgithub.com\u002FiDorgham\u002FWorkspace-Factory\u002Fblob\u002Fmaster\u002Ffactory\u002Flibrary\u002Farchive\u002Flegacy_pillars\u002F40_verticals\u002F11_industry_verticals\u002Fcrypto_web3\u002Ftests\u002Ftest_core.py",[111,141,151,161,176,191],{"skillNo":112,"name":113,"nameZh":6,"description":114,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":115,"categories":116,"keywords":129,"publishedAt":31},"01M6E3XK4PRPMQHM7Y98FQPTY1","zyte-api-automation","Automate Zyte API tasks via Rube MCP (Composio). Always search tools first for current schemas.","https:\u002F\u002Fgithub.com\u002F7dvq6yrkgs-stack\u002Fplaywright\u002Fblob\u002Fmain\u002Fskills\u002Fzyte-api-automation\u002FSKILL.md",[117,118,121,124],{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},{"categoryNo":119,"categoryName":120,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000010","后端与接口",{"categoryNo":122,"categoryName":123,"taxonomyType":20,"taxonomyTypeDesc":21},"01JBSEEDCAT000000000000023","Skill与智能体开发",{"categoryNo":125,"categoryName":126,"taxonomyType":127,"taxonomyTypeDesc":128},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[130,131,132,133,134,135,136,137,138,139,140],"zyte api automation","api","automation","MCP","tasks","search","Tools","first","automate","composio","via",{"skillNo":142,"name":143,"nameZh":6,"description":144,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":145,"categories":146,"keywords":149,"publishedAt":31},"01M6E3XFX6QSTR1QR59NFXJTMA","zylvie-automation","Automate Zylvie tasks via Rube MCP (Composio). Always search tools first for current schemas.","https:\u002F\u002Fgithub.com\u002F7dvq6yrkgs-stack\u002Fplaywright\u002Fblob\u002Fmain\u002Fskills\u002Fzylvie-automation\u002FSKILL.md",[147,148],{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},{"categoryNo":122,"categoryName":123,"taxonomyType":20,"taxonomyTypeDesc":21},[150,132,138,133,134,135,136,137,139,140],"zylvie automation",{"skillNo":152,"name":153,"nameZh":6,"description":154,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":155,"categories":156,"keywords":159,"publishedAt":31},"01M6E3XCX2GDYYCHN58ZJHT37M","zoominfo-automation","Automate Zoominfo tasks via Rube MCP (Composio). Always search tools first for current schemas.","https:\u002F\u002Fgithub.com\u002F7dvq6yrkgs-stack\u002Fplaywright\u002Fblob\u002Fmain\u002Fskills\u002Fzoominfo-automation\u002FSKILL.md",[157,158],{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},{"categoryNo":122,"categoryName":123,"taxonomyType":20,"taxonomyTypeDesc":21},[160,132,135,136,137,138,139,140,134,133],"zoominfo automation",{"skillNo":162,"name":163,"nameZh":6,"description":164,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":165,"categories":166,"keywords":169,"publishedAt":31},"01M6E3X9WJ2T73216WQHHTB9BD","zoho_mail-automation","Automate Zoho Mail tasks via Rube MCP (Composio): email sending, folders, labels, and mailbox management. Always search tools first for current schemas.","https:\u002F\u002Fgithub.com\u002F7dvq6yrkgs-stack\u002Fplaywright\u002Fblob\u002Fmain\u002Fskills\u002Fzoho_mail-automation\u002FSKILL.md",[167,168],{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},{"categoryNo":122,"categoryName":123,"taxonomyType":20,"taxonomyTypeDesc":21},[170,171,172,132,133,134,135,173,136,137,138,174,139,175,140],"mail","zoho mail automation","zoho","email","management","mailbox",{"skillNo":177,"name":178,"nameZh":6,"description":179,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":180,"categories":181,"keywords":187,"publishedAt":31},"01M6E3X719W648XZBW1EC6JQ64","zoho_invoice-automation","Automate Zoho Invoice tasks via Rube MCP (Composio): invoices, estimates, expenses, clients, and payment tracking. Always search tools first for current schemas.","https:\u002F\u002Fgithub.com\u002F7dvq6yrkgs-stack\u002Fplaywright\u002Fblob\u002Fmain\u002Fskills\u002Fzoho_invoice-automation\u002FSKILL.md",[182,183,184],{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},{"categoryNo":122,"categoryName":123,"taxonomyType":20,"taxonomyTypeDesc":21},{"categoryNo":185,"categoryName":186,"taxonomyType":127,"taxonomyTypeDesc":128},"01JBSEEDCAT000000000000040","财务",[188,172,132,134,135,136,137,138,189,190,139,140,133],"zoho invoice automation","tracking","payment",{"skillNo":192,"name":193,"nameZh":6,"description":194,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":195,"categories":196,"keywords":199,"publishedAt":31},"01M6E3X28JYTC3QTK32AQF7BYB","zoho_inventory-automation","Automate Zoho Inventory tasks via Rube MCP (Composio): items, orders, warehouses, shipments, and stock management. Always search tools first for current schemas.","https:\u002F\u002Fgithub.com\u002F7dvq6yrkgs-stack\u002Fplaywright\u002Fblob\u002Fmain\u002Fskills\u002Fzoho_inventory-automation\u002FSKILL.md",[197,198],{"categoryNo":18,"categoryName":19,"taxonomyType":20,"taxonomyTypeDesc":21},{"categoryNo":122,"categoryName":123,"taxonomyType":20,"taxonomyTypeDesc":21},[132,200,172,201,137,138,136,135,134,133,139,140,202,203,174],"inventory","zoho inventory automation","stock","orders"]