在 lambda 中捕获的 Constexpr 变量失去了它的 constexpr-ness
Constexpr variable captured inside lambda loses its constexpr-ness
此代码在 g++(coliru), but not 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): error C2131: expression did not evaluate to a constant
(6): note: failure was caused by a read of a variable outside its lifetime
(6): note: see usage of 'this'
哪一个(g++ 或 MSVC)是错误的?
“查看 'this' 的用法”中的 this
是什么??
如何在保持编译时保证的情况下解决这个问题?
在我的真实案例中,b (#1)
是一个复杂的语句,取决于其他几个 constexpr 变量。
Gcc 是对的。 b
(作为 constexpr
变量)实际上不需要 captured。
A lambda expression can read the value of a variable without capturing
it if the variable
- is constexpr and has no mutable members.
似乎如果制作 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();
}
和
How to work around it while keep the compile-time guarantee?
我们不能保持捕获变量的constexpr-ness。它们成为 lambda 闭包类型和 non-static data members can't be constexpr
.
的非静态数据成员
How to work around it while keep the compile-time guarantee?
将 constexpr bool
标记为 static
是一种解决方法。
见Demo
或者,您可以使用 if constexpr
中的条件,而不是将其分配给 bool
。如下所示:
if constexpr(std::is_same_v<T,int>)
见Demo
请注意,关于 lambda 表达式,constexpr
MSVC 出现了错误。
其中之一是:problems with capturing constexpr in lambda
另一个是:if constexpr in lambda
此代码在 g++(coliru), but not 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): error C2131: expression did not evaluate to a constant
(6): note: failure was caused by a read of a variable outside its lifetime
(6): note: see usage of 'this'
哪一个(g++ 或 MSVC)是错误的?
“查看 'this' 的用法”中的 this
是什么??
如何在保持编译时保证的情况下解决这个问题?
在我的真实案例中,b (#1)
是一个复杂的语句,取决于其他几个 constexpr 变量。
Gcc 是对的。 b
(作为 constexpr
变量)实际上不需要 captured。
A lambda expression can read the value of a variable without capturing it if the variable
- is constexpr and has no mutable members.
似乎如果制作 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();
}
和
How to work around it while keep the compile-time guarantee?
我们不能保持捕获变量的constexpr-ness。它们成为 lambda 闭包类型和 non-static data members can't be constexpr
.
How to work around it while keep the compile-time guarantee?
将 constexpr bool
标记为 static
是一种解决方法。
见Demo
或者,您可以使用 if constexpr
中的条件,而不是将其分配给 bool
。如下所示:
if constexpr(std::is_same_v<T,int>)
见Demo
请注意,关于 lambda 表达式,constexpr
MSVC 出现了错误。
其中之一是:problems with capturing constexpr in lambda
另一个是:if constexpr in lambda