MSVC是否存在Bug?Lambda按引用传参引发C2131常量求值错误
MSVC编译constexpr Lambda代码的问题
以下是演示该问题的最小示例代码:
constexpr auto foo = [](auto const& p) { return [p]{ return 1; }; }; void bar(){} constexpr auto baz = foo(bar); // C2131
MSVC(x64 v19.35)编译时出现如下错误:
<source>(6): error C2131: 表达式未计算为常量 <source>(2): note: 失败原因是读取未初始化的符号 <source>(2): note: 请查看 '<lambda_833637519c89a13e2555ac846bc40c61>::()::<lambda_13c809781a1aa438f693875c73cfce81>::p' 的使用 <source>(6): note: 求值的调用栈(最早调用在前)为 <source>(6): note: 正在计算函数 '<lambda_833637519c89a13e2555ac846bc40c61>::()::<lambda_13c809781a1aa438f693875c73cfce81> <lambda_833637519c89a13e2555ac846bc40c61>::operator ()<void(void)>(void (__cdecl &)(void)) const' <source>(2): note: 正在计算函数 '<lambda_833637519c89a13e2555ac846bc40c61>::()::<lambda_13c809781a1aa438f693875c73cfce81>::<lambda_13c809781a1aa438f693875c73cfce81>(void (__cdecl &)(void))' Compiler returned: 2
可行的解决方案包括:
- 将
bar改为函数对象:constexpr auto bar = []{}; - 将
foo的参数改为按值传递:constexpr auto foo = [](auto p) { return [p]{ return 1; }; }; - 对内部Lambda使用初始化捕获:
constexpr auto foo = [](auto const& p) { return [p = p]{ return 1; }; }; - 将
baz改为非constexpr:const auto baz = foo(bar);
这是MSVC的Bug。测试显示MSVC x64 v19.14可以正常编译该代码,而v19.35出现错误,说明是新版本的回归问题。该代码符合C++标准,接受它的编译器是合规的。
内容的提问来源于stack exchange,提问作者Enlico
相关产品推荐
相关产品推荐

