概念与约束
C++20引入了概念和约束的概念,用于限定模板类型实参的范围
新增了两个关键字concept与requires用于实现要求
requires
requires表达式
1 | requires(Type1 para1, Type2 para2, ...){ |
require可以有0-n个参数,大括号内有0-n个表达式
require表达式是常量表达式,编译时求值,依次对要求进行判断,遇到第一个无效表达式时返回false,若所有表达式都是有效或良构的,返回true
注意:每条要求不会被实例化或求值,仅用于判断有效
例1:
1 | template <typename T> |
其中最后一条为复合要求:
大括号里用于判断是否是有效的表达式,右箭头后面判断表达式的值是否符合某些条件
当T为int时,要求都可以成立,表达式的值为true
当T为string时,a++是无效的,表达式的值为false
例2:
1 | template<typename T> |
这个例子中,还有一种要求为条件要求:
格式为typename 表达式,判断类型是否有效
当T为int时,int内没有迭代器,表达式的值为false
当T为string时,string内嵌了迭代器,表达式的值为true
嵌套要求
语法:require 约束表达式
1 | template<typename T> |
此处约束表达式用于判断是否是浮点数
requires子句
语法:requires 常量表达式(约束)
1 | template<typename T> |
该函数模板设定了一个requires子句,判断传参是否为整型,只有满足该子句函数模板才能实例化,否则编译会报错
requires子句中的表达式也可以使用requires表达式
requires子句中也可以使用&&与||,前者需要满足所有约束,后者需要至少满足一项约束
concept
以上例子中的约束条件即为匿名概念,我们可以将约束条件定义为一个概念
1 | template<模板参数列表> |
定义后我们可以直接使用概念
1 | template<typename T> |
这里requires子句中使用了预定义的概念integral,定义如下:
1 | template<typename _Tp> |
或将模板中typename替换为概念
或使用概念+auto来定义形参
1 | bool is_odd(std::integral auto i){ |
通常定义概念时,概念应该有明确语义
<concept>头文件中也提供了许多预定义概念,大部分类型特征都有对应概念定义