Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/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++ 为SFINAE测试人员提供默认值零的原因是什么?_C++_Templates_C++11_Sfinae_Libc++ - Fatal编程技术网

C++ 为SFINAE测试人员提供默认值零的原因是什么?

C++ 为SFINAE测试人员提供默认值零的原因是什么?,c++,templates,c++11,sfinae,libc++,C++,Templates,C++11,Sfinae,Libc++,我注意到,boost和libc++/libstdc++中的许多代码在类似于 // libc++ http://llvm.org/svn/llvm-project/libcxx/trunk/include/memory namespace __has_pointer_type_imp { template <class _Up> static __two __test(...); template <class _Up> static char __test

我注意到,boost和libc++/libstdc++中的许多代码在类似于

// libc++ http://llvm.org/svn/llvm-project/libcxx/trunk/include/memory
namespace __has_pointer_type_imp
{
    template <class _Up> static __two __test(...);
    template <class _Up> static char __test(typename _Up::pointer* = 0);
}

template <class _Tp>
struct __has_pointer_type
    : public integral_constant<bool, sizeof(__has_pointer_type_imp::__test<_Tp>(0)) == 1>
{
};
//libc++http://llvm.org/svn/llvm-project/libcxx/trunk/include/memory
命名空间\u具有\u指针\u类型\u imp
{
模板静态二次检验(…);
模板静态字符测试(typename _Up::pointer*=0);
}
模板
结构具有指针类型
:公共积分常数
{
};
但是,这让我很困惑,为什么当他们显式地使用0进行调用时会出现这种情况。我记得在某个地方听说这是一个优化(在实例化模板时加快编译器的速度),但我不完全理解它是如何工作的。我查看了该标准,其中有一节简要描述了与模板参数推断相关的默认参数的情况

14.8.2

在模板参数推导过程中的某些点上,需要采用使用模板参数的函数类型,并用相应的模板参数替换这些模板参数。当任何显式指定的模板参数被替换到函数类型中时,这将在模板参数推导的开始处完成;当任何从默认参数推导或获得的模板参数被替换时,这将再次在模板参数推导的结束处完成

最后一点听起来与我的问题有关

当从默认参数推导或获得的任何模板参数被替换时,再次在模板参数推导结束时


然而,如果需要做更多的工作,这听起来像是优化的反面。是否有人有任何理由解释为什么0必须存在,它在没有它的情况下工作,但libc++中的每个SFINAE示例似乎都明确地将0放在那里,即使它们从未在没有参数的情况下调用该函数。

您提供了默认值,因为您希望能够不提供该参数,虽然情况仍在检查中

例如:

template<typename T,
        typename std::enable_if<
                std::is_floating_point_v<T>
                               >::type = 0>
void foo() { std::cout << "1"; }

然后,您可以为函数
foo
提供第二个参数,但通常您不想这样做。

我不知道确切的原因,但可能会在调用表达式中不传入
0
时引发“不明确的调用错误”,而不是假阴性(因为
版本匹配空参数,而非默认版本不匹配)它与空指针分析不相关吗?比如,默认的零可能会禁用空指针的静态分析,这反过来又避免了运行叮当作响的静态分析器时出现大量误报。出于同样的原因,可能还会略微加快编译速度。只是猜测一下……您应该在llvm邮件列表上询问(回到这里来启发我们;)
template<class T>
void foo(T t,
         typename std::enable_if<
                       std::is_floating_point_v<T>
                  >::type = 0) { std::cout << "2"; }