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

时间:2019-03-13 07:21:57

标签: 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>();
}
  

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

哪个(g ++或MSVC)是错误的?
查看'this'的用法”中的this是什么?

如何在保留编译时保证的情况下解决该问题?

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

1 个答案:

答案 0 :(得分:14)

Gcc是正确的。实际上,b(作为constexpr变量)不必为captured

  

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

还有

  

如何在保持编译时保证的情况下解决该问题?

我们无法保持所捕获变量的一致性。它们成为lambda闭包类型和non-static data members can't be constexpr的非静态数据成员。