为 SFINAE 测试仪提供默认值为零的原因是什么?

What is the reason for providing a default value of zero for SFINAE testers?

提问人:graphitemaster 提问时间:10/19/2014 最后编辑:user2864740graphitemaster 更新时间:3/5/2023 访问量:921

问:

我注意到大部分 boost 和 libc++/libstdc++ 在代码中显式为 SFINAE 提供了默认值零,例如

// 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>
{
};

但是,令我感到困惑的是,当他们以 0 显式进行调用时,为什么会出现这种情况。我记得在某处听说过这是一个优化(在实例化模板时加快编译器的速度),但我不完全明白这是如何工作的。我看了一下标准,它有一个部分简要描述了与模板参数推导相关的默认参数会发生什么。

14.8.2

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

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

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

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

C 模板 C++11 sfinae libc++

评论

3赞 Piotr Skotnicki 10/19/2014
我不知道确切的原因,但也许会在不传入调用表达式而不是假阴性时引发“模棱两可的调用错误”(因为版本匹配空参数,而非默认版本不匹配)0...
3赞 Antoine 11/7/2014
它与空指针分析无关吗?就像默认的零禁用空指针的静态分析一样,这反过来又避免了在运行 clang 静态分析器时出现大量误报。出于同样的原因,也可能略微加快编译速度。只是猜测......您应该在 llvm 邮件列表上提问(并返回此处以启发我们;))
0赞 Peter 9/14/2021
有各种各样的解释 - 除非阅读该库的设计/实现文档或(否则)询问开发人员,否则不可能知道。它可以像该库的开发人员遵循的样式指南中的指南一样简单。
0赞 PiotrNycz 3/22/2023
只是疯狂的猜测 - 但也许这是编译时间 - 我知道我们可能认为在没有默认参数值的情况下编译应该更容易 - 但也许对于这个编译器来说,情况恰恰相反 - 但我怀疑这是一个原因。
2赞 Swift - Friday Pie 9/19/2023
这里没有 SFINAE。为了大声疾呼,这是两个重载非成员函数的模板。

答: 暂无答案