【发布时间】:2018-06-22 08:24:04
【问题描述】:
考虑下面的std::pair 默认构造函数代码,来自Microsoft Visual Studio 15.4.5 附带的STL 实现:
template<class _Uty1 = _Ty1,
class _Uty2 = _Ty2,
class = enable_if_t<is_default_constructible<_Uty1>::value
&& is_default_constructible<_Uty2>::value>>
constexpr pair()
: first(), second()
{ // default construct
}
我设置了/std:c++latest 选项,所以,根据标准(我在这里使用草案n4659)我希望如果_Ty1 或@,这个构造函数将被排除在重载决议之外987654326@ 不是默认可构造的:
23.4.2 类模板对[pairs.pair]
显式常量表达式对();
效果:值初始化第一个和第二个。
备注:此构造函数不得参与重载决议 除非
is_default_constructible_v<first_type>为真并且is_default_constructible_v<second_type>是真的。 [注:此行为 可以通过带有默认模板的构造函数模板来实现 论据。]
在上面的实现中,排除的执行如下:
class = enable_if_t<is_default_constructible<_Uty1>::value
&& is_default_constructible<_Uty2>::value>
据我所知,SFINAE does not work 为模板类型参数默认值。
有趣的是,在 Microsoft Visual Studio 15.5.3 中,构造函数已更改为“正确版本”(“正确”基于我有限的模板知识):
template<class _Uty1 = _Ty1,
class _Uty2 = _Ty2,
enable_if_t<conjunction_v<
is_default_constructible<_Uty1>,
is_default_constructible<_Uty2>
>, int> = 0>
constexpr pair()
: first(), second()
{ // default construct
}
所以我想知道第一个实现是否正确,如果正确,将其更改为第二个有什么意义。
【问题讨论】:
-
模板类型参数的默认值只有在您有多个仅在默认值不同的重载时才会出现问题,因为默认值不参与重载解析。