Nej*_*ejc 19 c++ language-lawyer c++17
我试图了解下面的代码段是否应该根据标准进行编译.当我尝试使用最新版本的三个主要编译器编译它时,会发生以下情况:
-std=c++17标志):编译罚款;-std=c++17标志):也编译好;/std:c++17标志):编译器错误(见下文).发生此错误是因为std::optional<void>尽管代码被丢弃,MSVC编译器似乎试图实例化.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;
}
Run Code Online (Sandbox Code Playgroud)
MSVC出错:
Run Code Online (Sandbox Code Playgroud)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 ]
YSC*_*YSC 19
绝对是MSVC的一个错误.一个错误报告存在,据说已被固定在Visual Studio 2019预览.
if constexpr标准化为[stmt.if]/2:
如果
if语句是格式if constexpr,则条件的值应为bool类型的上下文转换常量表达式; 此表单称为constexpr if语句.
这适用.
如果转换条件的值为false,则第一个子语句是废弃语句,否则[...].
它也适用于你的程序中{ std::optional<T> val; }的废弃语句.
在封闭模板化实体(ndYSC
Bar<void, int>)的实例化期间,如果条件在其实例化之后不依赖于值,则不实例化丢弃的子语句(如果有的话).
与@ YSC的答案一样,相关的还有[temp.inst]/10:
实现不应隐式实例化函数模板,变量模板,成员模板,非虚拟成员函数,成员类,类模板的静态数据成员或constexpr if语句的子语句,除非这样的实例化是必须的.
| 归档时间: |
|
| 查看次数: |
929 次 |
| 最近记录: |