// ❌ C++17 之前:模板错误信息是灾难template <typename T>T add(T a, T b) { return a + b; }vector<int> v;add(v, v); // 编译报错 50 行,核心信息是 "vector 不能 +"// ✅ C++20:编译期检查 + 清晰的报错template <typename T> requires std::is_arithmetic_v<T>T add(T a, T b) { return a + b; }add(v, v); // 报错 1 行:constraint not satisfied: is_arithmetic_v<vector<int>>
定义 Concept
#include <concepts>// 方式 1: requires 表达式template <typename T>concept Addable = requires(T a, T b) { { a + b } -> std::convertible_to<T>; // a+b 合法且返回值可转为 T};// 方式 2: 组合已有 concepttemplate <typename T>concept Numeric = std::integral<T> || std::floating_point<T>;// 方式 3: 类型萃取template <typename T>concept Printable = requires(T t, std::ostream &os) { { os << t } -> std::same_as<std::ostream &>;};// 使用template <Addable T>T sum(const std::vector<T> &v) { T total{}; for (const auto &x : v) total += x; return total;}
requires 子句的四种写法
// ① requires 跟在 template 后面(推荐)template <typename T> requires std::integral<T>T gcd(T a, T b) { return b ? gcd(b, a % b) : a; }// ② concept 代替 typenametemplate <std::integral T>T abs(T x) { return x < 0 ? -x : x; }// ③ auto 缩写(C++20 简写模板)auto mul(std::integral auto a, std::integral auto b) { return a * b; }// ④ 尾置 requirestemplate <typename T>T inc(T x) requires std::integral<T> { return x + 1; }