mcpp-style-ref
为 mcpp 项目应用 Modern/Module C++ (C++23) 编码风格。适用于编写或审查带模块的 C++ 代码、命名标识符、组织 .cppm/.cpp 文件,或用户提及 mcpp、module C++、现代 C++ 风格时。
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
为 mcpp 项目应用 Modern/Module C++ (C++23) 编码风格。适用于编写或审查带模块的 C++ 代码、命名标识符、组织 .cppm/.cpp 文件,或用户提及 mcpp、module C++、现代 C++ 风格时。
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
| name | mcpp-style-ref |
| description | 为 mcpp 项目应用 Modern/Module C++ (C++23) 编码风格。适用于编写或审查带模块的 C++ 代码、命名标识符、组织 .cppm/.cpp 文件,或用户提及 mcpp、module C++、现代 C++ 风格时。 |
mcpp 项目的 Modern/Module C++ 风格参考。C++23 起适用(本仓库为 C++26),使用 import std。
本仓库落地示例:
modules/html_rewriter/(独立 workspace 成员,src/*.cppm模块 +tests/脱离 JS 引擎的单测)。
| 种类 | 风格 | 示例 |
|---|---|---|
| 类型/类 | PascalCase(大驼峰) | StyleRef, HttpServer |
| 对象/成员 | camelCase(小驼峰) | fileName, configText |
| 函数 | snake_case(下划线) | load_config_file(), parse_() |
| 私有 | _ 后缀 | fileName_, parse_() |
| 常量 | UPPER_SNAKE | MAX_SIZE, DEFAULT_TIMEOUT |
| 全局 | g 前缀 | gStyleRef |
| 命名空间 | 全小写 | mcpplibs, mylib |
import std 替代 #include <print> 和 #include <xxx>.cppm 作为模块接口;分离实现时用 .cppexport module module_name; — 模块声明export import :partition; — 导出分区import :partition; — 内部分区(不导出)// .cppm
export module a;
export import a.b;
export import :a2; // 可导出分区
import std;
import :a1; // 内部分区
topdir.subdir.filename(如 a.b, a.c)module_name:partition(如 a:a1, a.b:b1)a/c.cppm → a.c,b/c.cppm → b.cclass StyleRef {
private:
std::string fileName_; // 数据成员带 _ 后缀
public: // Big Five
StyleRef() = default;
StyleRef(const StyleRef&) = default;
// ...
public: // 公有接口
void load_config_file(std::string fileName); // 函数 snake_case,参数 camelCase
private:
void parse_(std::string config); // 私有函数以 _ 结尾
};
{} — int n { 42 },std::vector<int> v { 1, 2, 3 }std::string_viewstd::optional / std::expected 替代 int 错误码std::unique_ptr、std::shared_ptr;避免裸 new/deleteconstexpr、inline、concept 替代宏能用 C++ 实现的,一律用 C++ 实现。JS 侧只保留最薄的绑定/接口层。
mbun 的 JS builtin payload(modules/jsc/src/builtins/*.cppm 里的 raw string)
存在的理由是接到 JSC,不是承载实现。任何有实质逻辑的东西 —— 解析、状态机、
数据结构、编解码、路由、扫描 —— 属于独立的 workspace 成员(modules/<name>/src/*.cppm,
module mbun.<name>),由 JS 侧薄薄地调过去。
判定顺序(按此顺序问自己):
modules/router/ 有 358 行 FileSystemRouter 且零引用,
一条 lane 没有接线它,而是另写了 ~190 行 JS 架在 node:fs 上。测试从 0 到 29 绿,
但仓库现在有两份路由实现、其中一份没有任何调用者。这正是本规则要禁止的形状。
理由「那个模块缺目录扫描和 JSC 绑定,接线等于重写」不成立 —— 补齐缺的部分就是接线,
另写一份 JS 是绕过。tests/ 单测
(脱离 JS 引擎可测),这也是它比 JS payload 更该被选择的原因之一。Symbol.*、IDL 形状)、node/bun 的 JS 层协议(internal/* 的符号身份、
CJS/ESM 互操作),以及从真实源码 1:1 移植过来的 JS(见下)。与「直接移植」的关系,两者不冲突,但顺序要说清:
node 的 lib/** 是 JS,把它 1:1 机械移植进 JS payload 是当前阶段获取覆盖率
最快的路径,这是被明确授权的(覆盖优先,性能后置)。但移植进来的 JS 是有债的:
它应当在头部标注 1:1 translation of ...,并被视为后续下沉到 C++ 的候选,
而不是终局形态。规则的次序是:
性能是这条规则的理由,但不是当前的门禁。 现阶段不因为性能挡下移植; 但也不能因为「性能后期再做」就把新的实质逻辑写进 JS —— 那是在制造后期要还的债, 而接线一个已存在的 C++ 模块从来不是性能优化,是不重复造轮子。
两种写法均支持。
写法 A:合并 — 接口与实现同在一个 .cppm 中:
// mylib.cppm
export module mylib;
export int add(int a, int b) {
return a + b;
}
写法 B:分离 — 接口在 .cppm,实现在 .cpp(编译期隐藏实现):
// error.cppm(接口)
export module error;
export struct Error {
void test();
};
// error.cpp(实现)
module error;
import std;
void Error::test() {
std::println("Hello");
}
简单模块用写法 A;需隐藏实现或减少编译依赖时用写法 B。
工具链由 mcpp 自动解析(GCC 16),无需手动安装编译器:
xlings install mcpp -y # 一次性安装 mcpp
mcpp build # 根目录构建全部
mcpp test # 在成员目录内跑该成员单测(tests/*.cpp 自动发现)
新模块的落地方式:新建 modules/<name>/(mcpp.toml + src/<file>.cppm → 模块 mbun.<name>),注册进根 mcpp.toml 的 [workspace] members;消费方在其 mcpp.toml 声明 path 依赖。注意:mcpp 不把非导出分区放进 provider 图——用多个完整模块代替分区。
.cppm、.cpp)在本仓开发任何改动前用。规定 issue 先行的开发流程,按 bugfix / 优化 / 新功能分流;新功能须经 issue 充分讨论并在 .agents/docs 落地设计方案;衔接 tdd-workflow 与本体验证 / 测试 / CI / PR 规范。开发前先读本 skill。
向本仓提交 issue / 发起讨论时用。规定一份好问题反馈的 SOP——软件/版本、报错信息、初步分析、相关资料,并去除本地隐私(用户名/token 等替换)。凡要创建 issue、反馈 bug、发起讨论,先读本 skill 再动手。
调试 mbun 运行时测试失败/崩溃时用。提供仓库实测可用的定位配方——选二进制、单文件跑测、gdb 抓 backtrace、按 API 定位源码、常见坑排查清单、何时跳过。凡处理 bun 测试跑不过/段错误/hang/断言失败,先读本 skill 再动手,避免每个 task 重复摸索拖慢。
在 mbun 项目中开发任何功能或修复缺陷时使用。规定以 bun/node 原生测试集为验收标准的 TDD 开发循环、checkpoint 提交约定与记录流程。