C++中嵌套于requires-expression的requires是否引入requires-clause?
C++20里requires表达式嵌套requires的本质说明
先理清三个核心概念
- requires-clause(约束子句):直接给模板/概念加约束的语法,必须跟在模板参数列表或函数声明后面,写法是
requires 约束表达式,比如:template<typename T> requires std::is_const_v<T> // 这就是requires-clause void test(T); - requires-expression(约束表达式):一个能返回布尔值的独立表达式,写法是
requires (可选参数) { 要求序列 },它可以当requires-clause的约束条件用,也能在其他布尔表达式位置使用,比如:// 第一个requires是requires-clause,后面的requires { ... }是requires-expression template<typename T> void test() requires requires { typename T::value_type; }; - nested-requirement(嵌套要求):专门用在requires-expression大括号里的一种要求,写法是
requires 约束表达式;,用来验证某个约束是否为真。
你的示例代码解析
看你给出的这段代码:
template<typename T> … requires { requires std::is_const_v<T>; // 这是嵌套要求,不是requires-clause }
外层的requires { ... }是requires-expression,里面的requires std::is_const_v<T>;是标准定义的nested-requirement,不是requires-clause,原因很明确:
- 语法位置不同:requires-clause只能跟在模板/概念声明后面,而这个嵌套的requires是在requires-expression的大括号内部,属于要求序列的一部分。
- 标准定义独立:C++标准里[expr.prim.req.nested]单独定义了嵌套要求的语法,它和requires-clause是两种完全独立的语法结构,不存在谁是谁子集的关系。
关于“括号消失”的疑问
你觉得的“括号消失”其实是对两种语法设计的误解:
- requires-clause里的约束表达式可以加括号(比如
requires (std::is_const_v<T>)),但括号是可选的,不是必须的。 - 嵌套要求的语法本身就不需要括号:它的设计目标就是直接验证一个布尔常量表达式的真假,所以直接写
std::is_const_v<T>就行,根本不需要额外加括号——这不是什么“消失”,而是两种语法的规则本来就不一样。
内容的提问来源于stack exchange,提问作者Enlico
相关产品推荐
相关产品推荐

