plugins/languages/cpp/skills/template/SKILL.md
C++ template metaprogramming with concepts (C++20), CTAD, fold expressions, variable templates, constexpr / consteval / if consteval, deducing this (C++23), and C++26 static reflection. Use when writing generic libraries, compile-time computation, type traits, or replacing SFINAE / enable_if / CRTP with modern equivalents. Also triggers on "模板", "泛型", "concept", "requires", "CTAD", "fold expression", "constexpr", "consteval", "deducing this", "CRTP", "SFINAE", "type traits", "static reflection", "C++26 反射".
npx skillsauth add lazygophers/ccplugin cpp-templateInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
模板必须用 concepts 约束。所有 SFINAE / enable_if / 自定义 traits-only 技巧应迁移到 concepts + requires。
#include <concepts>
template<std::integral T>
T gcd(T a, T b) { return b == 0 ? a : gcd(b, a % b); }
template<std::floating_point T>
T lerp(T a, T b, T t) noexcept { return a + t * (b - a); }
template<std::ranges::range R>
void process(R&& r) { for (auto&& x : r) handle(x); }
template<std::invocable<int> F>
void apply(F&& f, int x) { std::invoke(std::forward<F>(f), x); }
template<typename T>
concept Serializable = requires(T t, std::ostream& os) {
{ t.serialize(os) } -> std::same_as<void>;
{ T::deserialize(os) } -> std::same_as<T>;
};
template<typename T>
concept Container = requires(T t) {
typename T::value_type;
typename T::iterator;
{ t.begin() } -> std::input_or_output_iterator;
{ t.end() } -> std::sentinel_for<decltype(t.begin())>;
{ t.size() } -> std::convertible_to<std::size_t>;
};
template<typename T>
concept Numeric = std::integral<T> || std::floating_point<T>;
// 复合
template<typename T>
concept SerializableContainer = Container<T> && Serializable<typename T::value_type>;
// 1. 约束模板参数
template<Numeric T>
T add(T a, T b) { return a + b; }
// 2. requires 子句
template<typename T> requires Numeric<T>
T mul(T a, T b) { return a * b; }
// 3. 尾随 requires
template<typename T>
T sub(T a, T b) requires Numeric<T> { return a - b; }
// 4. 简写 auto
Numeric auto square(Numeric auto x) { return x * x; }
简单单约束用形式 1 或 4;多约束或复杂表达式用形式 2。
std::pair p{1, 3.14}; // pair<int, double>
std::vector v{1, 2, 3}; // vector<int>
std::optional o{42}; // optional<int>
std::tuple t{1, "hi", 3.14}; // tuple<int, const char*, double>
// 自定义推导指引
template<typename T>
struct Wrapper { T value; };
template<typename T>
Wrapper(T) -> Wrapper<T>;
Wrapper w{42}; // Wrapper<int>
// 一元右折叠
template<typename... Args>
auto sum(Args... args) { return (args + ...); }
template<typename... Args>
bool all(Args... args) { return (args && ...); }
// 一元左折叠
template<typename... Args>
auto sum_left(Args... args) { return (... + args); }
// 二元折叠(带初值)
template<typename... Args>
auto sum_init(Args... args) { return (0 + ... + args); }
// 逗号折叠:对每参数执行动作
template<typename... Args>
void print_all(Args&&... args) {
(std::print("{} ", std::forward<Args>(args)), ...);
std::println("");
}
// constexpr:编译期或运行期均可
constexpr int factorial(int n) {
int r = 1;
for (int i = 2; i <= n; ++i) r *= i;
return r;
}
static_assert(factorial(5) == 120);
// consteval:必须编译期(C++20)
consteval int compile_only(int n) { return n * n; }
constexpr int x = compile_only(5); // OK
// int y = compile_only(runtime_val); // ERROR
// if consteval:编译/运行双路径(C++23)
constexpr double precise_sqrt(double);
constexpr double fast_sqrt(double x) {
if consteval { return precise_sqrt(x); }
else { return __builtin_sqrt(x); }
}
template<typename T>
inline constexpr bool is_numeric_v = std::integral<T> || std::floating_point<T>;
template<std::floating_point T>
inline constexpr T pi_v = static_cast<T>(3.14159265358979323846);
constexpr auto pi = pi_v<double>;
// 替代 CRTP 的递归 mixin
struct Counter {
int count_ = 0;
template<typename Self>
auto&& bump(this Self&& self) {
++self.count_;
return std::forward<Self>(self);
}
};
auto x = Counter{}.bump().bump().bump(); // chain on rvalue
auto& y = Counter{}.bump(); // chain to & if invoked on lvalue
// 递归 lambda
auto fact = [](this auto&& self, int n) -> int {
return n <= 1 ? 1 : n * self(n - 1);
};
static_assert(decltype(fact){}(5) == 120);
// 按值类别选择实现
struct Buffer {
std::vector<int> data_;
template<typename Self>
auto&& data(this Self&& self) noexcept {
return std::forward<Self>(self).data_;
}
};
#include <experimental/meta>
template<typename T>
constexpr auto field_count() {
return std::meta::nonstatic_data_members_of(^T).size();
}
struct Point { int x, y, z; };
static_assert(field_count<Point>() == 3);
// 字段名打印(草案语法)
template<typename T>
void dump(const T& obj) {
constexpr auto members = std::meta::nonstatic_data_members_of(^T);
[:expand(members):] >> [&]<auto m>() {
std::println("{} = {}", std::meta::name_of(m), obj.[:m:]);
};
}
使用前必查 __cpp_lib_reflection feature-test 宏,并准备 fallback。
| 旧技术 | 现代替代 |
|--------|----------|
| SFINAE std::enable_if_t | concepts + requires |
| Type traits 拼接 | concepts |
| CRTP for static polymorphism | Deducing this(C++23) |
| 标签分发 (tag dispatch) | concepts overload |
| 宏生成模板 | 变长模板 + 折叠 |
| 类型擦除手写 | std::function / std::any / std::variant |
| 借口 | 检查项 |
|------|--------|
| "SFINAE 我会写" | 是否换 concepts 提升错误信息? |
| "不用约束模板" | 模板是否被未来误用?错误信息是否可读? |
| "保留 CRTP" | 是否换 deducing this? |
| "运行期计算够用" | 常量是否可 constexpr/consteval? |
| "宏生成代码" | 是否用变长模板 + 折叠? |
| "enable_if 兼容旧编译器" | 项目 C++ 标准是否允许升级? |
if constevalstd::enable_iftools
--- name: trellisx-workspace description: 维护 `.trellis/task.md` 任务看板 —— trellis 缺的跨任务总览。**一个表格, 一行一个任务**, 列为 id/名称/描述/状态/阶段/进度/worktree (状态/阶段中文显示)。在 task create/start/阶段切换/archive 后**及时更新**对应行; 并**自动清理超 7 天的已完成行**防膨胀。保持看板与 task.json 实时一致。 when_to_use: 维护 / 创建 / 更新 `.trellis/task.md` 任务看板时; task 生命周期任一节点 (create/start/阶段推进/archive) 之后同步看板时; 用户问"当前有哪些任务 / 任务进度 / 任务看板"时。被 trellisx-flow 与 trellisx-apply 注入的流程引用。 user-invocable: true argument-hint: [show|update|sync|cleanup ...] [task id] arguments:
testing
强制以 Trellis task 闭环处理用户指定的请求 (自判新建/并入 → plan→exec→check→finish 全程不跳步)。**仅用户显式主动调用** (/trellisx-flow 或明确要求"强制走 task 处理这个"); **禁止自动 / 被动 / 推断式调用** —— 不要因为某个请求"看起来该建 task"就自动触发本 skill, 那是 apply 注入的 no_task 倾向的职责。
testing
把 强推task + subtask拆分 + worktree隔离 + 闭环收尾 四维度增量注入当前项目 .trellis/ (workflow.md 的 no_task/planning/in_progress 块 + spec 背书文档 + trellis 生命周期 hook worktree 自动化)。强推 task 与闭环为纯 prompt 软约束 (非平台 hook 硬拦截)。**纯增量追加, 绝不替换 trellis 原生文本** (no_task 分类+征同意/check/finish/前缀全保留)。幂等 (marker 包裹)。
development
Claude Code 会话历史整理 — 扫 ~/.claude/projects/**/*.jsonl 全部 session transcripts, 提取学习增量 (用户校正/决策/踩坑/L0 规则) → 全局记忆库 ~/.cortex/.wiki/memory/. 默认 --apply 落盘 (--dry-run opt-in 仅出 JSON plan 预览). 与 cortex-extract (L4-inbox 内部) 互补.