Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ MSVC std::pair实现:此处是否正确应用了SFINAE?_C++_Templates_Stl - Fatal编程技术网

C++ MSVC std::pair实现:此处是否正确应用了SFINAE?

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() {//默认构造 } 因此,我想知道第一个实现是否正确,如果正确,那么将其更改为第二个实现有

考虑以下来自Microsoft Visual Studio 15.4.5附带的STL实现的
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&);