C++ 如果constexpr在lambda中,则编译器行为不同
考虑以下代码。如果我对C++ 如果constexpr在lambda中,则编译器行为不同,c++,templates,c++17,if-constexpr,C++,Templates,C++17,If Constexpr,考虑以下代码。如果我对If constexpr的理解正确,则不应编译else分支,因此z()不应被视为错误 #include <type_traits> struct Z{}; template<typename T> void f(T z) { auto lam = [z]() { if constexpr(std::is_same<T, Z>::value) { } else { z(); } }; } i
If constexpr
的理解正确,则不应编译else
分支,因此z()
不应被视为错误
#include <type_traits>
struct Z{};
template<typename T>
void f(T z) {
auto lam = [z]() {
if constexpr(std::is_same<T, Z>::value) {
} else {
z();
}
};
}
int main() {
f(Z{});
}
如果删除了封闭的lambda,代码将在所有三个编译器上编译
我是做错了什么,还是不受支持,还是只是一个MSVC错误?这是一个MSVC错误。请提交错误报告 规则,从,是: 在封闭模板实体的实例化过程中,如果条件在实例化后不依赖于值,则不会实例化丢弃的子状态(如果有)
在实例化
f
期间,当我们实例化条件时,我们得到true
。这不依赖于值,因此不会实例化discard子语句(我们在其中执行z()
)。只有z()
的实例化才会导致错误,而且不应该发生MSVC被认为非常不支持C++特性。这么多年了,永远不会改变。您可能需要定义一个重载void f(Z)
作为一种解决方法。如果gcc和clang同意而MSVC不同意,那么它有99%的可能性是MSVC中的一个bug:)@bipll事实上,最近几个月它变得更符合标准:)您使用的MSV版本是什么?如果constexpr是最近才添加的,并且一开始就有问题,我不想费心分析这个问题,因为现在是星期三下午,但我只想说上面这些人可能是对的。毕竟,这就是if constexpr
的全部要点。
Microsoft (R) C/C++ Optimizing Compiler Version 19.14.26428.1 for x86
Copyright (C) Microsoft Corporation. All rights reserved.
if_constexpr.cpp
if_constexpr.cpp(10): error C2064: term does not evaluate to a function taking 0 arguments
if_constexpr.cpp(16): note: see reference to function template instantiation 'void f<Z>(T)' being compiled
with
[
T=Z
]