Lambda内获取constexpr变量:GCC正常VS编译失败问题及解决咨询
问题解答
1. 编译器合规性判断及原因
Visual C++ 符合C++标准,GCC的行为不符合标准。
原因:在常量表达式中调用lambda的非静态成员函数时,this指针必须指向一个常量表达式对象(即生命周期始于常量表达式求值期间的constexpr对象)。示例中func_do1Pass2是main函数中的自动存储期变量,其生命周期在程序进入main时就已开始,并非在sLambda内部的constexpr初始化过程中创建。因此调用func_do1Pass2()作为常量表达式的一部分,违反了C++标准中对常量表达式的限制。
参考依据:C++标准[expr.const]章节明确规定,常量表达式中不得引用自动存储期的对象,除非该对象是constexpr且其生命周期始于常量表达式求值过程中。
2. 兼容Visual C++的修改方案
由于原func_do1Pass2的模板成员函数未使用任何捕获的变量,可在标注区域直接用无捕获的constexpr lambda替代原调用,绕开对自动存储期lambda对象的依赖:
void testtt() { auto func_do1Pass2=[&]<int s>() { return 8; }; [&]<int s2>() { ///vvv can edit only here constexpr int g2 = []<int s>() { return 8; }.operator()<s2>(); ///^^^ can edit only here }.operator()<2>(); }
如果原func_do1Pass2的逻辑依赖模板参数s(例如return s;),只需同步修改临时lambda的逻辑即可,比如:
constexpr int g2 = []<int s>() { return s; }.operator()<s2>();
该修改的核心是用无捕获的constexpr lambda生成编译期常量,避免引用外层自动存储期的lambda对象,符合C标准对常量表达式的要求,可同时兼容GCC和Visual C。
内容的提问来源于stack exchange,提问作者cppBeginner
相关产品推荐
相关产品推荐

