c++20 Concepts的简写形式与requires 从句形式

打印 上一主题 下一主题

主题 949|帖子 949|积分 2847

在 C++20 Concepts 中,使用简写形式的 template<ConceptName T> 与使用完整形式的 template<typename T> requires ConceptName<T> 是等价的。以下是两种写法的具体转换:
原始写法(简写形式)

  1. template<typename T>
  2. concept Arithmetic = std::is_arithmetic_v<T>;
  3. template<Arithmetic T>  // 简写形式
  4. T add(T a, T b) { return a + b; }
复制代码
等效写法(requires 从句形式)

  1. template<typename T>
  2. concept Arithmetic = std::is_arithmetic_v<T>;
  3. template<typename T>    // 完整形式
  4. requires Arithmetic<T>  // requires 从句
  5. T add(T a, T b) { return a + b; }
复制代码
关键区别说明:

特性简写形式requires 从句形式语法布局template<ConceptName T>template<typename T> requires ...可组合性只能指定单个 Concept可通过逻辑运算符组合多个束缚束缚表达式位置模板参数声明中模板参数列表后的 requires 从句中实用场景简单束缚复杂束缚(必要组合多个条件时) 组合多个束缚的示例:

  1. template<typename T>
  2. concept Signed = std::is_signed_v<T>;
  3. template<typename T>
  4. requires Arithmetic<T> && Signed<T>  // 组合两个约束
  5. T negative(T value) {
  6.     return -value;
  7. }
  8. negative(5);     // OK
  9. negative(3.14);  // OK
  10. negative("123"); // 错误:不满足 Arithmetic 约束
  11. negative(2u);    // 错误:unsigned 不满足 Signed 约束
复制代码
两种形式的编译效果:


  • 错误信息对比
    1. add("hello", "world");  // 错误信息中会明确显示:
    2. // 简写形式:"constraints not satisfied for 'T'"
    3. // requires 从句形式:"constraint 'Arithmetic<T>' was not satisfied"
    复制代码
  • 元编程特性保留
    1. template<Arithmetic T>      // 两种形式均可配合
    2. struct Calculator {         // SFINAE、if constexpr 等特性
    3.     static_assert(Signed<T>);
    4. };
    复制代码
更复杂的束缚示例:

  1. template<typename T>
  2. concept Printable = requires(std::ostream& os, T val) {
  3.     { os << val } -> std::same_as<std::ostream&>;
  4. };
  5. template<typename T>
  6. requires Arithmetic<T> && Printable<T>
  7. void print_sum(T a, T b) {
  8.     std::cout << (a + b) << "\n";
  9. }
  10. print_sum(3, 5);    // OK:int 是算术类型且可打印
  11. print_sum(2.71, 3); // OK:double 符合条件
  12. print_sum(true, false); // 错误:bool 是算术类型但不符合 Printable(需要重载<<)
复制代码
尺度库风格的束缚:

  1. template<typename T>
  2. concept Addable = requires(T a, T b) {
  3.     { a + b } -> std::convertible_to<T>;
  4. };
  5. template<typename T>
  6. requires Addable<T>  // 替代 C++17 的 std::void_t 技巧
  7. T sum(T a, T b) { return a + b; }
复制代码
建议:当束缚条件简单时使用简写形式,必要组合多个束缚或必要更清晰的错误信息时使用 requires 从句形式。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

农妇山泉一亩田

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表