一、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 大价值:
- 可读性:
template <Hashable T>一眼就知道 T 需要具备什么能力。 - 错误信息:从"5 万行模板实例化堆栈"变成明确提示。
- 重载优先级:更特化的 Concept 优先级更高。