Token导航 LogoToken导航

Agent Skill · 待分类

cpp-templates-metaprogramming(cpp 模板元编程)

cpp-templates-metaprogramming 用于处理 GitHub 仓库、Issue、Pull Request 和代码协作信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要围绕仓库状态、代码变更或协作事项进行整理时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

cpp-templates-metaprogramming 是待分类类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为权限未标注;许可证为 MIT,第三方扫描已通过,按安装量在待分类类的 11,209 个 Skill 里排第 3,154。

总安装 1,139周安装 47GitHub Stars 142下载 372核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
MIT

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:cpp-templates-metaprogramming(cpp 模板元编程)
来源仓库:https://github.com/thebushidocollective/han
仓库路径:skills/cpp-templates-metaprogramming
安装命令:
npx skills add https://github.com/thebushidocollective/han --skill cpp-templates-metaprogramming
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。不同来源提供的安装方式可能略有差异;本站展示可直接复制的安装命令,安装前请核对来源页面。

skills.shnpx skills
npx skills add https://github.com/thebushidocollective/han --skill cpp-templates-metaprogramming

这个 Skill 是做什么的

这个 Skill 的分类还没最终确定,用法以来源仓库的说明为准。

cpp-templates-metaprogramming 深入模板元编程,支持编译期计算和类型操作。涵盖函数模板、SFINAE、concepts 和 constexpr 求值,实现零运行时开销。适用于高性能数学库、序列生成和类型特征提取,提升代码表达能力。

建议谨慎使用,避免过度复杂化导致调试困难,优先选择运行时多态替代方案。适用宿主包括 Codex、Claude、Cursor、Gemini CLI,接入前应确认版本、权限和运行环境要求。

来源仓库内路径:skills/cpp-templates-metaprogramming

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/thebushidocollective/han --skill cpp-templates…;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    权限没有明确标注,第一次使用时只给一个无关紧要的任务,观察它到底读了哪些文件和网络。

常见问题

6 条

cpp-templates-metaprogramming 怎么安装?

在终端执行 npx skills add https://github.com/thebushidocollective/han --skill cpp-templates-metaprogr…。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

cpp-templates-metaprogramming 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

cpp-templates-metaprogramming 需要什么权限?

权限级别没有明确标注。第一次使用时建议只给无关紧要的任务,观察它实际读写了哪些内容。

cpp-templates-metaprogramming 是免费的吗?

来源标注的许可证是 MIT。本站不代收任何费用,也不托管安装包;能否商用、要不要署名,以许可证原文为准。

cpp-templates-metaprogramming 用的人多吗?

公开数据是累计安装 1,139 次,近一周安装 47 次,下载 372 次,GitHub 142 星。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

cpp-templates-metaprogramming 安全吗?

第三方扫描结果为通过,但这只覆盖已知的静态检查项,不能替代自己读一遍源码和安装命令。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。
  • 3 个目录同时收录,说明这个 Skill 流传比较广。
  • 许可证明确为 MIT,商用和分发边界好判断。
  • 第三方扫描已通过,常见的高风险行为没有命中。

先想清楚的地方

  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理待分类类任务、又不想每次都手写提示词的人。
  • 需要许可证清楚、并且有第三方扫描结果的团队项目。

不太适合

  • 需要厂商级技术支持和 SLA 的生产系统。

待分类类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
infsh-cli

infsh CLI · Codex、Claude

4,374,576382权限未标注未明确未收录
ai-video-generation

AI 视频生成 · Codex、Claude

4,313,376382调用外部服务未明确有提醒
lark-openapi-explorer

云雀 OpenAPI 浏览器 · Codex、Claude

2,064,1209,011需要联网未明确有提醒
lark-workflow-standup-report

Lark 工作流程站立报告 · Codex、Claude

2,041,6328,978需要联网未明确通过
use-my-browser

使用我的浏览器 · Codex、Claude

1,848,49140操作浏览器未明确未通过
cpp-templates-metaprogramming

cpp 模板元编程 · 本页

1,139142权限未标注MIT通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

C++ Templates and Metaprogramming

Master C++ templates, template metaprogramming, SFINAE, concepts, and compile-time computation. This skill enables you to create generic, type-safe, and highly efficient C++ libraries with compile-time guarantees.

Function Templates

Basic Function Templates

// Simple function template
template<typename T>
T max(T a, T b) {
    return (a > b) ? a : b;
}

// Usage
int i = max(10, 20);           // T = int
double d = max(3.14, 2.71);    // T = double
// auto x = max(10, 3.14);     // ERROR: can't deduce T

// Multiple template parameters
template<typename T, typename U>
auto add(T a, U b) -> decltype(a + b) {
    return a + b;
}

auto result = add(5, 3.14);    // T = int, U = double, returns double

// C++14: simpler return type deduction
template<typename T, typename U>
auto multiply(T a, U b) {
    return a * b;
}

Template Specialization

// Primary template
template<typename T>
T absolute(T value) {
    return (value < 0) ? -value : value;
}

// Full specialization for const char*
template<>
const char* absolute<const char*>(const char* value) {
    return value; // Strings don't have absolute value
}

// Full specialization for std::string
template<>
std::string absolute<std::string>(std::string value) {
    return value;
}

// Usage
int a = absolute(-5);              // Uses primary template
const char* b = absolute("test");  // Uses const char* specialization

Function Template Overloading

// Overload 1: Generic template
template<typename T>
void print(T value) {
    std::cout << "Generic: " << value << std::endl;
}

// Overload 2: Pointer specialization
template<typename T>
void print(T* ptr) {
    std::cout << "Pointer: " << *ptr << std::endl;
}

// Overload 3: Non-template overload
void print(const char* str) {
    std::cout << "String: " << str << std::endl;
}

// Usage
int x = 42;
print(x);       // Overload 1
print(&x);      // Overload 2
print("hello"); // Overload 3 (exact match preferred)

Class Templates

Basic Class Templates

// Simple class template
template<typename T>
class Container {
    T value;

public:
    Container(T v) : value(v) {}

    T get() const { return value; }
    void set(T v) { value = v; }
};

// Usage
Container<int> intContainer(42);
Container<std::string> strContainer("hello");

// Multiple template parameters
template<typename K, typename V>
class KeyValuePair {
    K key;
    V value;

public:
    KeyValuePair(K k, V v) : key(k), value(v) {}

    K getKey() const { return key; }
    V getValue() const { return value; }
};

KeyValuePair<std::string, int> pair("answer", 42);

Template Member Functions

template<typename T>
class Array {
    T* data;
    size_t size;

public:
    Array(size_t s) : size(s), data(new T[s]) {}
    ~Array() { delete[] data; }

    // Template member function
    template<typename Func>
    void forEach(Func func) {
        for (size_t i = 0; i < size; ++i) {
            func(data[i]);
        }
    }

    // Template conversion operator
    template<typename U>
    operator Array<U>() const {
        Array<U> result(size);
        for (size_t i = 0; i < size; ++i) {
            result.data[i] = static_cast<U>(data[i]);
        }
        return result;
    }
};

// Usage
Array<int> arr(5);
arr.forEach([](int& x) { x *= 2; });

Class Template Specialization

// Primary template
template<typename T>
class Storage {
    T data;

public:
    Storage(T d) : data(d) {}
    T get() const { return data; }
};

// Full specialization for pointers
template<typename T>
class Storage<T*> {
    T* data;

public:
    Storage(T* d) : data(d) {}
    T* get() const { return data; }
    T& operator*() { return *data; }
};

// Full specialization for bool (bit optimization)
template<>
class Storage<bool> {
    unsigned char data : 1;

public:
    Storage(bool d) : data(d) {}
    bool get() const { return data; }
};

Partial Template Specialization

// Primary template
template<typename T, typename U>
class Pair {
public:
    T first;
    U second;
    void info() { std::cout << "Generic pair" << std::endl; }
};

// Partial specialization: both types the same
template<typename T>
class Pair<T, T> {
public:
    T first;
    T second;
    void info() { std::cout << "Same type pair" << std::endl; }
};

// Partial specialization: second type is pointer
template<typename T, typename U>
class Pair<T, U*> {
public:
    T first;
    U* second;
    void info() { std::cout << "Second is pointer" << std::endl; }
};

// Usage
Pair<int, double> p1;    // Generic
Pair<int, int> p2;       // Same type
Pair<int, double*> p3;   // Second is pointer

Template Parameters

Type Parameters

// Single type parameter
template<typename T>
class Vector {
    T* data;
};

// Multiple type parameters
template<typename T, typename Allocator>
class CustomVector {
    T* data;
    Allocator alloc;
};

// Default type parameters
template<typename T, typename Compare = std::less<T>>
class Set {
    Compare comp;
public:
    bool less(const T& a, const T& b) {
        return comp(a, b);
    }
};

Non-Type Parameters

// Integer non-type parameter
template<typename T, size_t N>
class Array {
    T data[N];

public:
    constexpr size_t size() const { return N; }

    T& operator[](size_t i) { return data[i]; }
    const T& operator[](size_t i) const { return data[i]; }
};

Array<int, 10> arr1;  // Array of 10 ints
Array<double, 5> arr2; // Array of 5 doubles

// Bool non-type parameter
template<typename T, bool IsSorted>
class Container {
public:
    void insert(T value) {
        if constexpr (IsSorted) {
            insert_sorted(value);
        } else {
            insert_unsorted(value);
        }
    }

private:
    void insert_sorted(T value) { /* ... */ }
    void insert_unsorted(T value) { /* ... */ }
};

// Pointer non-type parameter (C++17)
template<auto* Ptr>
class StaticWrapper {
public:
    auto& get() { return *Ptr; }
};

Template Template Parameters

// Template template parameter
template<typename T, template<typename> class Container>
class Stack {
    Container<T> data;

public:
    void push(const T& value) {
        data.push_back(value);
    }

    T pop() {
        T value = data.back();
        data.pop_back();
        return value;
    }
};

// Usage
Stack<int, std::vector> intStack;
Stack<double, std::deque> doubleStack;

// With multiple parameters
template<typename T,
         template<typename, typename> class Container,
         typename Allocator = std::allocator<T>>
class AdvancedStack {
    Container<T, Allocator> data;
};

Variadic Templates

Parameter Packs

// Basic variadic template
template<typename... Args>
void print(Args... args) {
    (std::cout << ... << args) << std::endl; // C++17 fold expression
}

print(1, 2, 3, "hello", 3.14);

// Get pack size
template<typename... Args>
constexpr size_t count(Args... args) {
    return sizeof...(args);
}

size_t n = count(1, 2, 3, 4); // 4

// Recursive parameter pack processing (pre-C++17)
template<typename T>
void print_recursive(T value) {
    std::cout << value << std::endl;
}

template<typename T, typename... Args>
void print_recursive(T first, Args... rest) {
    std::cout << first << " ";
    print_recursive(rest...); // Recursive call
}

Fold Expressions (C++17)

// Unary right fold: (args op ...)
template<typename... Args>
auto sum(Args... args) {
    return (args + ...);
}

auto result = sum(1, 2, 3, 4, 5); // 15

// Unary left fold: (... op args)
template<typename... Args>
auto sum_left(Args... args) {
    return (... + args);
}

// Binary right fold: (args op ... op init)
template<typename... Args>
auto sum_with_init(Args... args) {
    return (args + ... + 0);
}

// Binary left fold: (init op ... op args)
template<typename... Args>
auto multiply_with_init(Args... args) {
    return (1 * ... * args);
}

// Logical fold expressions
template<typename... Args>
bool all_true(Args... args) {
    return (args && ...);
}

template<typename... Args>
bool any_true(Args... args) {
    return (args || ...);
}

// Comma fold for side effects
template<typename... Args>
void print_all(Args... args) {
    (std::cout << ... << args) << std::endl;
}

Variadic Class Templates

// Tuple-like class
template<typename... Types>
class Tuple;

// Base case: empty tuple
template<>
class Tuple<> {};

// Recursive case
template<typename Head, typename... Tail>
class Tuple<Head, Tail...> : private Tuple<Tail...> {
    Head value;

public:
    Tuple(Head h, Tail... t) : Tuple<Tail...>(t...), value(h) {}

    Head& head() { return value; }
    Tuple<Tail...>& tail() { return *this; }
};

// Usage
Tuple<int, double, std::string> t(42, 3.14, "hello");

// Variadic template with perfect forwarding
template<typename... Args>
auto make_unique_custom(Args&&... args) {
    return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}

SFINAE (Substitution Failure Is Not An Error)

Basic SFINAE

// Enable if type has begin() method
template<typename T>
auto process(T container) -> decltype(container.begin(), void()) {
    std::cout << "Container with begin()" << std::endl;
}

// Enable if type is arithmetic
template<typename T>
auto process(T value)
    -> typename std::enable_if<std::is_arithmetic<T>::value>::type {
    std::cout << "Arithmetic type" << std::endl;
}

// Usage
std::vector<int> vec;
process(vec);    // First overload
process(42);     // Second overload

Std::enable_if

// Enable function for integral types only
template<typename T>
typename std::enable_if<std::is_integral<T>::value, T>::type
increment(T value) {
    return value + 1;
}

// C++14: cleaner syntax with enable_if_t
template<typename T>
std::enable_if_t<std::is_integral<T>::value, T>
decrement(T value) {
    return value - 1;
}

// As template parameter (C++14)
template<typename T, typename = std::enable_if_t<std::is_floating_point<T>::value>>
T half(T value) {
    return value / 2;
}

// Multiple enable_if conditions
template<typename T>
std::enable_if_t<std::is_pointer<T>::value &&
                 !std::is_const<std::remove_pointer_t<T>>::value, void>
modify(T ptr) {
    *ptr = {};
}

Tag Dispatching

// Implementation functions with tags
template<typename Iterator>
void advance_impl(Iterator& it, int n, std::random_access_iterator_tag) {
    it += n; // O(1) for random access
}

template<typename Iterator>
void advance_impl(Iterator& it, int n, std::input_iterator_tag) {
    while (n--) ++it; // O(n) for input iterators
}

// Dispatch function
template<typename Iterator>
void advance(Iterator& it, int n) {
    advance_impl(it, n,
        typename std::iterator_traits<Iterator>::iterator_category());
}

If Constexpr (C++17)

// Replaces many SFINAE use cases
template<typename T>
auto process(T value) {
    if constexpr (std::is_integral_v<T>) {
        return value * 2;
    } else if constexpr (std::is_floating_point_v<T>) {
        return value * 3.14;
    } else if constexpr (std::is_pointer_v<T>) {
        return *value;
    } else {
        return value;
    }
}

// Variadic template with if constexpr
template<typename T, typename... Args>
void print(T first, Args... rest) {
    std::cout << first;
    if constexpr (sizeof...(rest) > 0) {
        std::cout << ", ";
        print(rest...);
    } else {
        std::cout << std::endl;
    }
}

Concepts (C++20)

Defining Concepts

#include <concepts>

// Simple concept
template<typename T>
concept Integral = std::is_integral_v<T>;

// Concept with requires expression
template<typename T>
concept Incrementable = requires(T x) {
    { ++x } -> std::same_as<T&>;
    { x++ } -> std::same_as<T>;
};

// Compound concept
template<typename T>
concept Number = std::is_arithmetic_v<T>;

template<typename T>
concept SignedNumber = Number<T> && std::is_signed_v<T>;

// Concept with multiple requirements
template<typename T>
concept Container = requires(T c) {
    typename T::value_type;
    typename T::iterator;
    { c.begin() } -> std::same_as<typename T::iterator>;
    { c.end() } -> std::same_as<typename T::iterator>;
    { c.size() } -> std::convertible_to<std::size_t>;
};

Using Concepts

// Constrain function template
template<Integral T>
T add(T a, T b) {
    return a + b;
}

// Requires clause
template<typename T>
    requires Integral<T>
T multiply(T a, T b) {
    return a * b;
}

// Abbreviated function template (C++20)
auto divide(Integral auto a, Integral auto b) {
    return a / b;
}

// Constrain class template
template<Container C>
class Processor {
    C container;
public:
    void process() {
        for (auto& item : container) {
            // Process item
        }
    }
};

// Multiple constraints
template<typename T>
    requires std::is_arithmetic_v<T> && std::is_signed_v<T>
T absolute(T value) {
    return value < 0 ? -value : value;
}

Concept Specialization

// Different implementations based on concepts
template<typename T>
void process(T value) {
    if constexpr (Integral<T>) {
        std::cout << "Processing integer: " << value << std::endl;
    } else if constexpr (std::floating_point<T>) {
        std::cout << "Processing float: " << value << std::endl;
    } else {
        std::cout << "Processing other: " << value << std::endl;
    }
}

// Concept-based overloading
void handle(Integral auto value) {
    std::cout << "Integral: " << value << std::endl;
}

void handle(std::floating_point auto value) {
    std::cout << "Float: " << value << std::endl;
}

void handle(Container auto container) {
    std::cout << "Container of size: " << container.size() << std::endl;
}

Type Traits

Standard Type Traits

#include <type_traits>

// Type properties
static_assert(std::is_integral_v<int>);
static_assert(std::is_floating_point_v<double>);
static_assert(std::is_pointer_v<int*>);
static_assert(std::is_array_v<int[5]>);
static_assert(std::is_const_v<const int>);

// Type relationships
static_assert(std::is_same_v<int, int>);
static_assert(std::is_base_of_v<Base, Derived>);
static_assert(std::is_convertible_v<int, double>);

// Type modifications
using NoConst = std::remove_const_t<const int>;      // int
using NoRef = std::remove_reference_t<int&>;         // int
using NoPointer = std::remove_pointer_t<int*>;       // int
using AddConst = std::add_const_t<int>;              // const int
using AddPointer = std::add_pointer_t<int>;          // int*

// Conditional types
using Type = std::conditional_t<true, int, double>;  // int

Custom Type Traits

// Check if type has size() method
template<typename T, typename = void>
struct has_size : std::false_type {};

template<typename T>
struct has_size<T, std::void_t<decltype(std::declval<T>().size())>>
    : std::true_type {};

template<typename T>
inline constexpr bool has_size_v = has_size<T>::value;

// Usage
static_assert(has_size_v<std::vector<int>>);
static_assert(!has_size_v<int>);

// Check if type is iterable
template<typename T, typename = void>
struct is_iterable : std::false_type {};

template<typename T>
struct is_iterable<T, std::void_t<
    decltype(std::declval<T>().begin()),
    decltype(std::declval<T>().end())>>
    : std::true_type {};

template<typename T>
inline constexpr bool is_iterable_v = is_iterable<T>::value;

Template Metaprogramming

Compile-Time Computation

// Factorial at compile time
template<int N>
struct Factorial {
    static constexpr int value = N * Factorial<N - 1>::value;
};

template<>
struct Factorial<0> {
    static constexpr int value = 1;
};

constexpr int fact5 = Factorial<5>::value; // 120

// Fibonacci at compile time
template<int N>
struct Fibonacci {
    static constexpr int value = Fibonacci<N - 1>::value + Fibonacci<N - 2>::value;
};

template<>
struct Fibonacci<0> {
    static constexpr int value = 0;
};

template<>
struct Fibonacci<1> {
    static constexpr int value = 1;
};

constexpr int fib10 = Fibonacci<10>::value; // 55

Type Lists

// Type list definition
template<typename... Types>
struct TypeList {};

// Get size of type list
template<typename List>
struct Length;

template<typename... Types>
struct Length<TypeList<Types...>> {
    static constexpr size_t value = sizeof...(Types);
};

// Get type at index
template<size_t Index, typename List>
struct At;

template<size_t Index, typename Head, typename... Tail>
struct At<Index, TypeList<Head, Tail...>>
    : At<Index - 1, TypeList<Tail...>> {};

template<typename Head, typename... Tail>
struct At<0, TypeList<Head, Tail...>> {
    using type = Head;
};

// Usage
using MyList = TypeList<int, double, char, std::string>;
static_assert(Length<MyList>::value == 4);
using SecondType = At<1, MyList>::type; // double

CRTP (Curiously Recurring Template Pattern)

// Static polymorphism via CRTP
template<typename Derived>
class Base {
public:
    void interface() {
        static_cast<Derived*>(this)->implementation();
    }

    void common_functionality() {
        std::cout << "Common code" << std::endl;
    }
};

class Derived1 : public Base<Derived1> {
public:
    void implementation() {
        std::cout << "Derived1 implementation" << std::endl;
    }
};

class Derived2 : public Base<Derived2> {
public:
    void implementation() {
        std::cout << "Derived2 implementation" << std::endl;
    }
};

// Usage
template<typename T>
void use(Base<T>& obj) {
    obj.interface(); // No virtual function overhead
}

Derived1 d1;
Derived2 d2;
use(d1); // Derived1 implementation
use(d2); // Derived2 implementation

Expression Templates

// Expression template for lazy evaluation
template<typename E>
class VecExpression {
public:
    double operator[](size_t i) const {
        return static_cast<const E&>(*this)[i];
    }

    size_t size() const {
        return static_cast<const E&>(*this).size();
    }
};

class Vec : public VecExpression<Vec> {
    std::vector<double> data;

public:
    Vec(size_t n) : data(n) {}

    double& operator[](size_t i) { return data[i]; }
    double operator[](size_t i) const { return data[i]; }
    size_t size() const { return data.size(); }

    template<typename E>
    Vec& operator=(const VecExpression<E>& expr) {
        for (size_t i = 0; i < size(); ++i) {
            data[i] = expr[i];
        }
        return *this;
    }
};

// Addition expression
template<typename E1, typename E2>
class VecSum : public VecExpression<VecSum<E1, E2>> {
    const E1& lhs;
    const E2& rhs;

public:
    VecSum(const E1& l, const E2& r) : lhs(l), rhs(r) {}

    double operator[](size_t i) const {
        return lhs[i] + rhs[i];
    }

    size_t size() const { return lhs.size(); }
};

// Operator overload
template<typename E1, typename E2>
VecSum<E1, E2> operator+(const VecExpression<E1>& lhs,
                          const VecExpression<E2>& rhs) {
    return VecSum<E1, E2>(static_cast<const E1&>(lhs),
                          static_cast<const E2&>(rhs));
}

// Usage: single loop evaluation
Vec v1(1000), v2(1000), v3(1000), v4(1000);
v4 = v1 + v2 + v3; // Efficient: no temporary vectors

Constexpr and Consteval

Constexpr Functions

// Constexpr function (can be compile-time or runtime)
constexpr int square(int n) {
    return n * n;
}

constexpr int value1 = square(5);  // Compile-time
int x = 5;
int value2 = square(x);            // Runtime

// Constexpr with complex logic (C++14+)
constexpr int fibonacci(int n) {
    if (n <= 1) return n;

    int a = 0, b = 1;
    for (int i = 2; i <= n; ++i) {
        int temp = a + b;
        a = b;
        b = temp;
    }
    return b;
}

// Constexpr with std::array
constexpr auto make_array() {
    std::array<int, 5> arr{};
    for (size_t i = 0; i < arr.size(); ++i) {
        arr[i] = i * i;
    }
    return arr;
}

constexpr auto squares = make_array();

Consteval Functions (C++20)

// Must be evaluated at compile-time
consteval int cube(int n) {
    return n * n * n;
}

constexpr int value3 = cube(5);  // OK: compile-time
// int y = 5;
// int value4 = cube(y);         // ERROR: not compile-time

// is_constant_evaluated
constexpr int conditional_compute(int n) {
    if (std::is_constant_evaluated()) {
        // Compile-time path
        return n * n;
    } else {
        // Runtime path (might use hardware instructions)
        return n * n; // Could use intrinsics
    }
}

Template Debugging

Compile-Time Debugging

// Print type at compile time (causes error with type info)
template<typename T>
struct DebugType;

// DebugType<decltype(value)> debug; // Error shows type

// Static assert for debugging
template<typename T>
void check_type(T value) {
    static_assert(std::is_integral_v<T>, "T must be integral");
    static_assert(sizeof(T) >= 4, "T must be at least 4 bytes");
}

// Concept for better error messages
template<typename T>
concept AtLeast4Bytes = sizeof(T) >= 4;

template<AtLeast4Bytes T>
void process(T value) {
    // If T doesn't satisfy concept, clear error message
}

Template Error Reduction

// Before C++20: cryptic errors
template<typename T>
void old_process(T value) {
    value.size(); // Error if T doesn't have size()
}

// C++20: Clear concept-based errors
template<typename T>
concept HasSize = requires(T t) {
    { t.size() } -> std::convertible_to<std::size_t>;
};

template<HasSize T>
void new_process(T value) {
    value.size(); // Clear error if T doesn't satisfy HasSize
}

// Static assert for early error
template<typename T>
void checked_process(T value) {
    static_assert(HasSize<T>, "T must have size() method");
    value.size();
}

Best Practices

  1. Prefer concepts over SFINAE (C++20): Clearer error messages and more readable constraints
  2. Use type traits for type inspection: Leverage std::is_same, std::is_integral, etc.
  3. Prefer constexpr over template metaprogramming: More readable and debuggable
  4. Use if constexpr for conditional compilation: Replaces many SFINAE use cases
  5. Avoid deep template recursion: Can cause long compile times and errors
  6. Use abbreviated function templates carefully: Can hide important type information
  7. Provide clear error messages: Use static_assert or concepts to guide users
  8. Forward perfectly with std::forward: Preserve value categories in template code
  9. Use variadic templates for flexible interfaces: Better than overload sets
  10. Document template requirements: Specify what operations types must support

Common Pitfalls

  1. Two-phase lookup issues: Name lookup behaves differently in templates
  2. Dependent name resolution: Must use typename and template keywords correctly
  3. Template instantiation bloat: Each instantiation creates new code
  4. Compile-time explosion: Complex metaprogramming can cause long compiles
  5. Obscure error messages: Template errors can be difficult to understand
  6. Missing typename keyword: Required for dependent type names
  7. Missing template keyword: Required for dependent template names
  8. Forgetting std::forward: Breaks perfect forwarding
  9. Concept subsumption issues: More specific concepts must subsume less specific
  10. Constexpr limitations: Not all operations allowed in constexpr context

When to Use

Use this skill when:

  • Creating generic algorithms and data structures
  • Building reusable library code
  • Implementing compile-time computation
  • Constraining template parameters with concepts
  • Performing type introspection and manipulation
  • Optimizing performance with zero-cost abstractions
  • Creating domain-specific embedded languages (DSELs)
  • Implementing static polymorphism with CRTP
  • Building expression template libraries
  • Teaching or learning advanced C++ techniques

Resources

平台分布

Claude Code

29.11%
按下载量换算108

OpenCode

23.11%
按下载量换算86

Cursor

17.09%
按下载量换算64

Codex

12.22%
按下载量换算45

windsurf

8.51%
按下载量换算32

Antigravity

3.22%
按下载量换算12

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

权限未标注

当前来源未能明确判断权限范围,默认进入异常复核队列。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。

继续浏览同类 Skills