在 GCC 中,在 lambda 内部,我可以从非 constexpr 模板 lambda 获取 constexpr 变量,但在 Visual C++ 中不行

问题描述 投票:0回答:1

此代码在 gcc 中编译良好,但在 Visual C++ 中编译失败。

MCVE = https://godbolt.org/z/K7d5PEs65

int main(){
      int localVariable=0; //some local variable
      auto lamb=[&]<int s>() {
          if constexpr(s==5){localVariable=7;}
          ///^ may modify some local variables
          return 8;
      };
      constexpr int gOk=lamb.operator()<2>();
      [&]<int s2>() {
          ///vvv can edit only here
          constexpr int gFail=lamb.operator()<s2>();
          ///^^^ can edit only here
      }.operator()<2>();
}

错误 C2131 表达式未计算为常量

我需要

gFail
成为
constexpr
变量,而
lamb
有时会产生运行时副作用,具体取决于模板变量
s
的值。

请给出Visual C++案例的参考和解决方法。

c++ templates lambda c++20 constexpr
1个回答
0
投票

我相信您遇到的问题是 MSVC 的错误/缺陷,但我会让语言律师提供确切的原因(或反驳我的陈述)。 通常,在这些情况下我所做的是将

constexpr
值打包在一个整数常量中。这是MSVC可以咀嚼的东西:

#include <iostream>
#include <cstdlib>
int main(){
      int localVariable=0; //some local variable
      auto lamb=[&]<int s>() {
          if constexpr(s==5){localVariable=7;}
          return std::integral_constant<int, 8>{};
      };
      constexpr int gOk=lamb.operator()<2>().value;
      [&]<int s2>() {
          auto tmp = lamb.operator()<s2>();
          constexpr int gFail=tmp; //tmp implicitly casted from integral_constant to int.
      }.operator()<2>();
}
对于 MSVC,需要明确拼写

tmp
。如果您直接分配给
gFail
,您会得到相同的“不计算为常量”。

不幸的是,这不遵循您的“只能在此处编辑”指南。

© www.soinside.com 2019 - 2024. All rights reserved.