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
UI/UX 与布局设计——做界面布局/结构/导航/组件/交互的设计决策。触发:做UI/UX/布局/排版/导航/组件/交互/栅格/响应式/图表选型/字体配对。按媒介路由 HTML/Web、原生 App(iOS/Android/桌面)、CLI、TUI。需后端动态系统不适用;配色/主题/色板走姊妹 skill design-color。
tools
主题与配色设计——做颜色搭配/调色板/主题/品牌色阶/暗模式的设计决策。触发:选配色/调色/主题/色板/品牌色/暗模式/对比度/色盲/UI风格。按媒介路由 HTML/Web(CSS变量)、原生App(平台token)、CLI(ANSI)、TUI(真彩/256/16降级)。保证可访问性(对比度/色盲安全)。需后端动态系统不适用;UI/UX 布局/组件/交互走姊妹 skill design-uiux。
tools
跨任意组件(plugin/skill/agent/command)的验证驱动优化循环纪律 skill。当用户要优化某个已有组件却无明确方向、或要防止改了反而更差(自评乐观偏差 / 多维同改归因失效 / 为凑分加废话膨胀)、或要把一套通用「评分→单变量改→改后验证严格更好才留否则回滚→触顶停」的纪律套到任意组件上时使用。管优化过程本身的纪律(validation gate / ratchet / 独立验证 / 触顶停),不评单组件深度(交 skill-dev),不查插件接线(交 plugin-dev)。仅手动 /optimize-any 触发。
data-ai
两层规则记忆 (基于 .skein/spec)。planning 时 recall 召回相关规则、task finish 后 sediment 沉淀学习 + prune 自动精简过期/重复/断链规则。core 常驻硬规 + recall 按需召回, 经判定门自动写盘 (不逐次问用户)。产出 .skein/spec 下 core/recall 规则文件 + index。另支持空仓 bootstrap 播种规则基线、记忆大面积失效 (大重构/换栈) 时 reconstruct 可逆归档后按项目类型分型重建、maintain 手动体检 (超预算/stale/断链/重复/废弃, --apply 自动修复)、auto-fix (Stop hook 写 .pending-fix 标记 → main 派 skein-specer bg 跑 maintain --apply 全自动修, 断链只报告)。