这个问题是关于template<class...Types> class variant:
根据variant.variant/3,variant没有模板参数实例化的程序是错误的.
到目前为止,这么清楚.现在我有一个关于转换构造函数(template<class T> constexpr variant(T&& t) noexcept(see below))的问题:
variant.variant/variant.ctor-16.1表示转换构造函数不应参与重载决策,除非:
sizeof ...(类型)非零
(......以及我现在不关心的一些其他要求).
我的问题是,当variant没有模板参数已经使我的程序格式错误时,为什么还要关心我的转换构造函数是否参与重载决策?
看看MSVC和libstdc ++  - 实现variant它们实际上有一个enable_if_t<sizeof...(_Types) != 0>转换构造函数的声明.为什么?
作为本文的一部分,添加了"sizeof ...(Types)非零"这一条款[variant.ctor]:对类模板参数推导集成到标准库中的一些改进也允许variant支持.
相关摘录:
启用变体支持
以下代码无法编译
Run Code Online (Sandbox Code Playgroud)variant<int, double> v1(3); variant v2 = v1; // Ill-formed! <--THIS由于这种自然代码很有用并且它的失败令人困惑,我们建议它得到支持.实际上,在采用p0510r0禁止之前
variant<>,上述代码按预期工作,因为variant<>在重载集中的某些演绎指南中会出现这种情况.由于在采用p0510r0时不清楚是否考虑了构造函数模板参数推导,我们希望考虑variant<>在这种情况下不允许产生硬错误.措辞 (强调增加)
改变§23.7.3.1p16[variant.ctor]如下:
备注:除非sizeof...(Types)是非零,否则此函数不应参与重载决议,除非is_same_v<decay_t<T>, variant>是false,除非decay_t<T>是,除非是,除非表达式为FUN ,否则不是专业化in_place_type_t或专业化(std :: forward(t))(FUN是上面提到的虚函数集)形成良好.in_place_index_tis_constructible_v<Tj, T>true
因此std::variant v2 = v1;,在没有考虑添加的子句的编译器版本中失败(如GCC 7.1.请参阅DEMO),但在更高版本上成功(从GCC 7.2开始.请参阅DEMO).
| 归档时间: | 
 | 
| 查看次数: | 196 次 | 
| 最近记录: |