文档目录

一、constexpr —— 让代码在编译期运行

// 编译期阶乘
constexpr int factorial(int n) {
    if (n <= 1) return 1;
    return n * factorial(n - 1);
}

int arr[factorial(5)]; // ✅ 编译期求值,arr 大小 120

int x = 5;
int y = factorial(x); // ❌ 运行时调用(x不是编译期常量)
constexpr int z = factorial(5); // ✅ 编译期调用

consteval(C++20):强制编译期执行,不允许运行时调用。

consteval int double_it(int n) {
    return n * 2;
}

constexpr int x = double_it(21);  // ✅ 42
int y = double_it(21);            // ✅ 编译器推导为 constexpr
int z = double_it(x);             // ✅ 可以
int runtime_val = std::rand();
int w = double_it(runtime_val);   // ❌ 编译错误:consteval 不允许运行时调用

二、C++20 Concepts —— 摆脱 SFINAE 噩梦

// 定义 Concept
template <typename T>
concept Hashable = requires(T a) {
    { std::hash<T>{}(a) } -> std::convertible_to<size_t>;
};

// 使用 Concept 约束模板
template <Hashable T>
void process_hash(const T& value) {
    auto h = std::hash<T>{}(value);
}

// 或者更简约的写法
void process_hash(const Hashable auto& value) {
    auto h = std::hash<T>{}(value);
}

// 错误信息对比
process_hash(42);   // ✅ int 有 hash 特化
process_hash("hello"); // ✅ const char* 有 hash 特化

struct MyType {};
process_hash(MyType{}); // ❌ 编译错误:"MyType 不满足 Hashable 约束"
                        //    而不是几万行的模板实例化失败堆栈!

Concepts 的 3 大价值:

  1. 可读性:template <Hashable T> 一眼就知道 T 需要具备什么能力。
  2. 错误信息:从"5 万行模板实例化堆栈"变成明确提示。
  3. 重载优先级:更特化的 Concept 优先级更高。