gpt4 book ai didi

c++ - MSVC std::pair 实现:SFINAE 是否在此处正确应用?

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:26:40 26 4
gpt4 key购买 nike

考虑以下 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 中的任何一个,这个构造函数将被排除在重载决议之外。或 _Ty1不是默认可构造的:

23.4.2 Class template pair [pairs.pair]

EXPLICIT constexpr pair();

Effects: Value-initializes first and second.

Remarks: This constructor shall not participate in overload resolution unless is_default_constructible_v<first_type> is true and is_default_constructible_v<second_type> is true. [ Note: This behavior can be implemented by a constructor template with default template arguments.]

在上面的实现中,排除是按如下方式执行的:

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
}

所以我想知道第一个实现是否正确,如果正确,将其更改为第二个有什么意义。

最佳答案

并不是说 SFINAE 在默认模板参数中不起作用;这是因为它们不算作签名的一部分,因此将您的 SFINAE 机器放在那里意味着如果您想构建一个重载集,您必须以其他方式使签名不同。

因此,这很好:

template<class T, class=std::enable_if_t<std::is_integral_v<T>>>
T meow();

template<class T, class=std::enable_if_t<!std::is_integral_v<T>>>
void meow();

因为签名不同(返回类型是函数模板签名的一部分——但不是函数);这是:

template<class T, class=std::enable_if_t<std::is_integral_v<T>>>
void meow(T);

template<class T, class=std::enable_if_t<!std::is_integral_v<T>>>
void meow(const T&);

但这不是(它重新声明相同的函数模板,因此尝试为相同的模板参数提供两次默认模板参数):

template<class T, class=std::enable_if_t<std::is_integral_v<T>>>
void meow(const T&);

template<class T, class=std::enable_if_t<!std::is_integral_v<T>>>
void meow(const T&);

特别是关于pair 构造函数模板,如果不知道其他构造函数模板是什么,您无法真正判断它是否正确。也就是说,如果他们弄错了,我会感到非常惊讶;任何问题都应该可以通过简单的单元测试轻松发现。

关于c++ - MSVC std::pair 实现:SFINAE 是否在此处正确应用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48233615/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com