C++中requires表达式的局部参数能否被lambda捕获?编译器预期行为解析
Requires表达式局部参数的Lambda捕获合法性分析
问题场景
和函数类似,requires表达式可以通过参数列表引入局部约束变量;块作用域定义的Lambda表达式支持无初始化捕获。那么在requires表达式内部,是否允许Lambda捕获这些局部约束变量?
示例代码如下:
template<typename T> concept C = requires( T t ) { [t]{ [t]{}; }; };
这段代码可以被GCC和MSVC正常编译,但Clang会抛出错误:error: constraint variable 't' cannot be used in an evaluated context。
标准依据与预期行为
从C++标准的角度分析:
- requires表达式中的
t是约束变量,其作用域仅限于requires表达式内部,在该范围内名称查找完全合法。 - 代码中的
[t]{ [t]{}; };属于简单要求(simple requirement),整个表达式是未求值操作数。标准对简单要求的定义是:仅需检查表达式的语法正确性、静态语义合法性(比如名称查找、类型匹配等),不需要执行实际的求值逻辑。 - Lambda捕获约束变量
t的操作,在未求值上下文中只是做静态语法和语义校验——验证t是否在捕获范围内、捕获语法是否合规,不需要实际生成捕获的对象或执行任何运行时逻辑。
因此,这段代码的写法符合C++标准要求,编译器应当接受该代码。GCC和MSVC的行为符合标准预期,而Clang的报错属于实现层面的问题,错误地将未求值上下文的捕获判定为“求值上下文”中的非法使用。
内容的提问来源于stack exchange,提问作者Fedor
相关产品推荐
相关产品推荐

