嵌套Lambda隐式捕获constexpr局部变量,MSVC编译失败谁合规?
问题:嵌套Lambda中constexpr变量的捕获与C++标准一致性
一段嵌套Lambda的代码在GCC和Clang中可正常编译,但MSVC会抛出错误error C3493: 'i' cannot be implicitly captured because no default capture mode has been specified,仅当将变量i声明为static时MSVC才接受代码。需要明确哪种编译器的行为符合C++标准,以及背后的原因。
最小复现代码
int main() { []() { // MSVC要求必须声明为static constexpr int i = []() { return 42; }(); []() { static_assert(i == 42); }(); }(); return 0; }
标准一致性分析
GCC和Clang的行为符合C++标准,MSVC的处理不符合标准规定,原因如下:
- 根据C++标准,
constexpr类型的局部变量若由常量表达式初始化,则在使用时不构成odr-use(单一定义规则使用)。对于这类变量,编译器可以直接将其常量值嵌入代码,无需依赖变量的存储实例,因此Lambda不需要捕获它。 - 内层Lambda中的
static_assert是编译期检查,i的值在编译阶段就完全确定,对i的引用属于常量表达式使用,完全不涉及对变量存储的访问,自然不需要捕获。
MSVC错误地将该constexpr变量判定为需要捕获的对象,这是不符合标准的行为。
内容的提问来源于stack exchange,提问作者Oersted
相关产品推荐
相关产品推荐

