21

这段代码在 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>();
}

(6): 错误 C2131: 表达式未计算为常数
(6): 注意: 失败是由在其生命周期之外读取变量引起的
(6): 注意: 请参阅“this”的用法

哪一个(g++ 或 MSVC)错了?“查看‘this’的用法”中有
什么内容??this

如何在保持编译时保证的同时解决它?

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

4

2 回答 2

17

海合会是对的。b(作为constexpr变量)实际上不需要被捕获

lambda 表达式可以读取变量的值而不捕获它,如果变量

  • 是 constexpr 并且没有可变成员。

海合会直播

似乎如果制作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 直播

如何在保持编译时保证的同时解决它?

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

于 2019-03-13T07:40:20.677 回答
9

如何在保持编译时保证的同时解决它?

标记constexpr boolstatic作为解决方法。

演示

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

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

演示

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

于 2019-03-13T07:40:30.737 回答