当前位置: 首页 > article >正文

C++20 概念与约束(2)—— 初识概念与约束

1、概念

        C++20 中引入新的编译期关键字 concept 用于创建概念。个人认为将其翻译为“构思”更为贴切。直接使用时,它更像一个只能用于模板的布尔类型关键字。

         而如果用于模板中,他会将模板类型先带入自身,当自身条件为 true 才会实例化模板,否则该模板被弃置。因此该关键字几乎全用于 SFINAE 规则。

         如上图, foo 将因为找不到匹配模板而报错。

        因此只需要通过逻辑条件运算符将多条语句进行列举即可。

        此外,概念还可用于简写模板之中,只需写在 auto 之前即可:

        同样,第一个 foo 调用符合概念,而传入 char 类型违反概念,因此该行报错,找不到模板。

        因此概念是通过约定模板需要满足的条件来使用 SFINAE 规则的关键字。

2、约束

        C++20 中引入另一个关键字 requires。不同于 concept , requires 关键字可以使用户无需定义概念而对模板添加实例化的条件。当然不仅仅如此,个人觉得 requires 的用法特别混乱,没办法简单几句话概括其用法。

        用英语单词来作对比,requires有动词和名词两种用法。在语法中也可以这么理解,主句的 requires 是动词,从句则是名词。

1、requires主句

        requires 主句后跟布尔值类型的表达式,表示要求达成后续条件。因此,之前例子中的概念也可用 requires 主句将其写到同一个模板中。

        此外,因为概念的表达式值也是布尔类型,因此以下写法也是合法的: 

        题外话,这时候还可以对比 bool 类型的常量模板,会发现布尔类型的常量模板和概念特别相似,只不过概念可以放到定义模板的尖括号中,而布尔常量不行:

        总之,requires 主句只需要后续表达式值为 true 则允许实例化模板,否则该模板将被放弃匹配。 

2、requires从句

        requires 从句与主句不同,它后面必须跟花括号,括号中的表达式必须在编译期能够确定。并且,requires 从句的结果只有语法不允许和 true 两种,也就是说,在非模板中使用,只要编译能通过,它的值一定是 true ,它更像是条件的集合。根据此特性,requires 从句往往用于模板中以匹配 SFINAE 规则。

        上图中两个 requires 第一个必然是主句,用于要求后续条件符合。第二个 requires 便是从句,它要求 T::type1 和 T::type2 是合法语句才会返回 true 。 X 类型不符合该规则,该模板被弃置, foo<X> 无匹配模板。而 Y 符合该条件, foo<Y> 将被实例化。

        此外,从句的 requires 还允许后续紧跟一对括号用于类型的编译期的实例化。编译期的实例化并不会被真正实例化,只是用于检查实例化后的对象是否符合某种特性。

        可见该约束要求类型支持解引用和同类型相加的操作, X 类型不符合该规则,只有 foo<Y> 能被正确实例化。

3、再说主句与从句

        提个毫无意义的小 tip ,requires 的主句和从句可以互相无限嵌套。

         再次重申,requires 子句只要能返回值,只有可能是 true 这一种结果。在非模板中,如果 requires 子句中的表达式非法是直接报错,非模板环境不存在 SFINAE 机制。

        如上图,报错信息与直接在 main 函数中使用该表达式的报错没有任何不同。 

        不可认为 requires 主句是因为从句不符合语法而返回 false 而启动 SFINAE 机制。之所以模板中的约束使得模板不被实例化是因为子句条件不符合而被抛弃,类似于以下模板中第二个模板默认类型形参的不符合。


http://www.kler.cn/a/386752.html

相关文章:

  • MySQL高级(二):一条更新语句是如何执行的
  • change buffer:到底应该选择普通索引还是唯一索引
  • androidstudio下载gradle慢
  • 华为大变革?仓颉编程语言会代替ArkTS吗?
  • 文件输入输出——NOI
  • 【C++】C++11特性(上)
  • 三分钟学会Docker基本操作,快速入门容器技术!
  • 还在网盘?分享百兆级大文件传输工具--Wormhole:不限速在线文件传输下载利器
  • Java 类和对象
  • Spring Boot开发入门教程
  • 第二届计算机网络技术与电子信息工程国际学术会议(CNTEIE 2024,12月6-8日)
  • Android 应用插件化及其进程关系梳理
  • Python异常检测 - LSTM(长短期记忆网络)
  • “2048”游戏网页版html+css+js
  • 100种算法【Python版】第40篇——卡恩算法
  • 基于springboot信用分析管理系统设计与实现
  • Linux下的 MySQL 中添加用户并设置远程访问
  • 十六:Spring Boot (1)-- spring-boot-starter 应用
  • EHOME视频平台EasyCVR视频融合平台支持哪些摄像机接入?监控摄像头镜头的种类有哪些?
  • 启明云端触觉智能与您相约2024年慕尼黑国际电子元器件博览会,不见不散!
  • 半年总结-还有很多要学习
  • clickhouse自增id的处理
  • JS 循环语句
  • 如何学习C++游戏开发
  • 基于微信小程序的实习管理系统(附源码,文档)
  • 2024-11-5 学习人工智能的Day22 openCV(4)