C++ MSVC std::pair实现:此处是否正确应用了SFINAE?
考虑以下来自Microsoft Visual Studio 15.4.5附带的STL实现的C++ MSVC std::pair实现:此处是否正确应用了SFINAE?,c++,templates,stl,C++,Templates,Stl,考虑以下来自Microsoft Visual Studio 15.4.5附带的STL实现的std::pair默认构造函数代码: 据我所知,SFINAE用于模板类型参数的默认值 有趣的是,在Microsoft Visual Studio 15.5.3中,构造函数已更改为“正确版本”(“基于我有限的模板知识,正确版本”): template=0> constexpr对() :first(),second() {//默认构造 } 因此,我想知道第一个实现是否正确,如果正确,那么将其更改为第二个实现有
std::pair
默认构造函数代码:
据我所知,SFINAE用于模板类型参数的默认值
有趣的是,在Microsoft Visual Studio 15.5.3中,构造函数已更改为“正确版本”(“基于我有限的模板知识,正确版本”):
template=0>
constexpr对()
:first(),second()
{//默认构造
}
因此,我想知道第一个实现是否正确,如果正确,那么将其更改为第二个实现有什么意义。这并不是说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();
模板
T喵喵();
模板>
虚空喵喵();
因为签名不同(返回类型是函数模板签名的一部分,但不是函数);这就是:
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&);
模板
空喵(T);
模板>
虚空喵喵(const T&);
但事实并非如此(它重新声明了相同的函数模板,因此尝试为相同的模板参数提供两次默认模板参数):
模板
虚空喵喵(const T&);
模板>
虚空喵喵(const T&);
特别是关于
对
构造函数模板,如果不知道其他构造函数模板是什么,就无法真正判断它是否正确。也就是说,如果他们弄错了,我会非常惊讶;任何问题都可以通过简单的单元测试轻松发现。我认为它们都是正确的,但第二个更灵活。我认为这是正确的,因为SFINAE的使用要点是确保构造函数仅在元素可以默认构造时可用,并且不允许选择所述构造函数的不同重载
根据定义,只有一个版本的构造函数(或任何其他函数)接受0个参数,因此,重载解析在这里不是问题。模板类型参数默认值只有在多个重载的默认值不同时才是问题,因为默认值不参与重载解析。啊,我现在明白了!问题是,我从来没有仔细阅读过链接问题,虽然它也给出了解释。你这么认为,但不是完全确定?
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
}
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&);