lambda内部捕获的constexpr变量失去了其constexpr-ness

Constexpr variable captured inside lambda loses its constexpr-ness

本文关键字:失去 constexpr-ness 变量 constexpr 内部 lambda      更新时间:2023-10-16

此代码在g (coliru)中填充了罚款,而不是MSVC(Godbolt和My 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>();
}

(6):错误C2131:表达未评估为常数
(6):注意:失败是由于其寿命以外的变量读取
引起的 (6):注意:请参阅" this''

的用法

哪个(G 或MSVC)是错误的?
什么是" "中的 this,请参见'this''的用法?

如何在保留编译时保证的同时如何处理?

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

gcc是正确的。b(作为constexpr变量)实际上不需要捕获。

lambda表达式可以读取变量的值而无需捕获 如果变量

  • 是constexpr,没有可变成员。

GCC Live

似乎如果制作b static,那么MSVC可以访问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();
}

MSVC Live

如何在保持编译时保证的同时如何处理?

我们无法保留捕获变量的constexpr-。它们成为lambda关闭类型的非静态数据成员,而非静态数据成员不能为constexpr

如何在保持编译时保证的同时如何处理?

constexpr bool标记为static作为工作。

请参阅 demo

另外,您可以在if constexpr中使用该条件,而不是将其分配给bool。如下:

if constexpr(std::is_same_v<T,int>)

请参阅 demo

请注意,有关lambda表达的constexpr已为MSVC提出了错误。
其中之一是:在lambda中捕获Constexpr的问题
另一个是:如果lambda中的constexpr