C(八)concept和requires的直观认识
concept输入模板参数,输出一个bool类型字面量。
例如:autoisintstd::integralint;std::coutThetypeofstd::integralint:typetostringdecltype(std::integralint)()std::endl;std::coutThevaluetypeofstd::integralint:typetostringdecltype((std::integralint))()std::endl;
输出:Thetypeofstd::integralint:boolThevaluetypeofstd::integralint:bool
concept最后输出的结果的值类型是个纯右值,也就是个字面量。我们可以将concept的结果当成字面量使用,也可以用字面量替代concept的结果,在requires中使用。concept结果当字面量用
例如,输入输出:autoisintstd::integralint;std::coutstd::boolalpha;std::coutisint:isintstd::endl;
输出:isint:true字面量当concept用templatetypenameTrequirestruevoidg(Ta){std::coutastd::endl;}intmain(){g(10);}
输出:10requires
requires分两种,一种是在template下面的,用来判断concept是否满足的,例如下面的例子:templatetypenameTrequiresstd::integralTvoidg(Ta){std::coutastd::endl;}
一种是带表达式的,和一个函数形式类似,例如:templatetypenameTconceptcanexecrequires(Ta){a10;};intmain(){std::coutstd::boolalpha;std::coutcanexecintstd::endl;std::coutcanexecfloatstd::endl;}
输出:truefalse
其中:requires(Ta){a10;};
并不实际求值,只是判断{}内的表达式能否运行。再看个例子:templatetypenameTconceptcanexec1requires(Ta){false;};intmain(){std::coutstd::boolalpha;std::coutcanexec1intstd::endl;std::coutcanexec1floatstd::endl;}
输出:truetrue
所以,对于requires(。。。){}来说,只要{}中的表达式能运行,就会返回真。intmain(){autocanexec2requires(inta,intb){ab;};std::coutstd::boolalpha;std::coutcanexec2std::endl;}
输出:true
requires(。。。){}主要用来判断表达式能否运行,返回一个bool字面量
当然,也可以直接在template中运用templatetypenameTrequiresrequires{false;}voidg1(Ta){std::coutastd::endl;}g1(10)
输出:10
requires表达式中还可以再嵌套第一种requires
如果直接使用,会报错:intmain(){autocanexec2requiresstd::integralint;std::coutstd::boolalpha;std::coutcanexec2std::endl;}error:expected{beforestdintmain(){autocanexec2requires{requiresstd::integralint;};std::coutstd::boolalpha;std::coutcanexec2std::endl;}
输出:true
还可以这样用intmain(){floata2。2;intb3;autof〔〕typenameT(Ta){autocanexec2requires(Tvalue){requiresstd::integralT;};returncanexec2;};std::coutstd::boolalpha;std::coutf(a)std::endl;std::coutf(b)std::endl;}
这样用:templatetypenameTrequiresrequires{requiresstd::integralint;}voidg1(Ta){std::coutastd::endl;}
用来约束lambda表达式autof〔〕typenameTrequiresstd::integralT(Ta){};