在lambda内部捕获的Constexpr变量失去了其解释性

jav*_*ver 19 c++ lambda language-lawyer c++17 if-constexpr

这段代码可以在g ++(coliru)中很好地编译,但是在MSVC(Godbolt和我的VS2017)中却不能。

#include <type_traits>
#include <iostream>
template<class T> void f(){
    constexpr bool b=std::is_same_v<T,int>; //#1
    auto func_x=[&](){
        if constexpr(b){ //#error
        }else{
        }
    };
    func_x();
}
int main(){
    f<int>();
}
Run Code Online (Sandbox Code Playgroud)

(6):错误C2131:表达式未求值为常数
(6):注意:失败是由于在其生命周期之外读取变量导致的
(6):注意:请参见'this'的用法

哪一个(g ++或MSVC)错了?“ 请参阅'this'的用法
是什么??this

在保留编译时保证的同时如何解决呢?

在我的真实情况下,b (#1)一个复杂的语句取决于其他一些constexpr变量。

son*_*yao 15

海湾合作委员会是正确的。b(作为constexpr变量)实际上不需要被捕获

Lambda表达式可以读取变量的值,而无需捕获变量

  • 是constexpr,没有可变成员。

GCC LIVE

看来b staticMSVC是否可以b不捕获就进行访问。

template<class T> void f(){
    constexpr static bool b=std::is_same_v<T,int>;
    auto func_x=[](){
        if constexpr(b){
        }else{
        }
    };
    func_x();
}
Run Code Online (Sandbox Code Playgroud)

MSVC LIVE

在保留编译时保证的同时如何解决呢?

我们不能为捕获的变量保持一致性。它们成为lambda闭包类型的非静态数据成员constexpr而非静态数据成员则不能

  • @NicolBolas,因为b是constexpr,因此直接对其​​执行从左到右的转换并不构成odr的使用。有关标准参考,请参见[basic.def.odr] / 3。 (3认同)

P.W*_*P.W 8

在保留编译时保证的同时如何解决呢?

constexpr boolas 标记为static替代方法。

观看演示

或者,您可以在中使用条件,if constexpr而不是将其分配给bool。如下所示:

if constexpr(std::is_same_v<T,int>)
Run Code Online (Sandbox Code Playgroud)

观看演示

请注意,关于constexprlambda表达式,MSVC出现了一些错误。
一种是:在lambda中捕获constexpr的问题,
另一种是:如果在lambda中捕获constexpr