【发布时间】:2019-01-10 10:45:15
【问题描述】:
我试图了解下面的 sn-p 是否应该根据标准编译。当我尝试使用三个主要编译器的最新版本进行编译时,会出现以下情况:
-
✓ Clang(7.0.0 版,带有
-std=c++17标志):编译良好; -
✓ GCC(8.2 版,带有
-std=c++17标志):也可以正常编译; -
❌ MSVC(19.16 版,带有
/std:c++17标志):编译器错误(见下文)。
发生错误是因为 MSVC 编译器似乎试图实例化 std::optional<void>,尽管代码已被丢弃。 GCC 和 Clang 似乎没有这样做。
标准是否明确定义了在这种情况下应该发生什么?
#include <optional>
#include <type_traits>
template<typename T, typename... Args>
struct Bar
{
void foo(Args... args)
{
if constexpr(!std::is_same_v<T, void>) // false
{
// MSVC compiler error occurs because of the line below; no error occurs when compiling with GCC and Clang
std::optional<T> val;
}
}
};
int main(int argc, char** argv)
{
Bar<void, int> inst;
inst.foo(1);
return 0;
}
MSVC 出错:
C:/msvc/v19_16/include\optional(87): error C2182: '_Value': illegal use of type 'void' C:/msvc/v19_16/include\optional(128): note: see reference to class template instantiation 'std::_Optional_destruct_base<_Ty,false>' being compiled with [ _Ty=void ]
【问题讨论】:
-
看起来像一个 MSVC 错误,因为 IRC 如果 constexpr 下的部分依赖于模板参数,则不应实例化它,除非分支已被采用。
-
为了它的价值:
if constexpr的动机或多或少正是为了使这样的示例编译。
标签: c++ language-lawyer c++17