c++ - enable_if 如何帮助选择类模板的特化?

标签 c++ template-meta-programming template-specialization enable-if class-template

我对 SFINAE 有基本的了解,我想我理解了很多关于如何 std::enable_if 的例子。利用它来选择函数模板特化,但我很难理解它如何用于类模板。

以下例子来自cppreference.com's explanation of std::enable_if :

template<class T, class Enable = void>
class A {}; // primary template

template<class T>
class A<T, typename std::enable_if<std::is_floating_point<T>::value>::type> {
}; // specialization for floating point types

我无法理解如何使用 std::enable_if这样有助于选择专业。 (我不怀疑它确实如此。)

当编译器看到类似 A<float> specialized; 的声明时,它将看到两个可能的模板实例化:

  1. “主模板”A<T, Enable>其中 T是类型 float Enable 是类型 void (因为默认值)。
  2. 专业A<T, void>其中 T是类型 floatvoid是带有 enable_if 的表达式的结果.

那些不是模棱两可的吗?两者都有效地导致 A<T, void> ,那么为什么选择特化呢?

在另一种情况下,例如 A<int> primary; ,编译器的选项似乎是:

  1. 小学,A<T, Enable> , 其中T是类型 intEnable是类型 void .
  2. 专业,A<T, ?> , 其中T是类型 int?代表我完全迷路的地方。在这种情况下,enable_if条件为假,所以它没有定义 type ,这给你留下了 A<int, typename > .那不是语法错误吗?即使面对 SFINAE?

最佳答案

来自 partial specialization 上的引用资料类模板:

When a class or variable (since C++14) template is instantiated, and there are partial specializations available, the compiler has to decide if the primary template is going to be used or one of its partial specializations.

If only one specialization matches the template arguments, that specialization is used

在这种情况下,如果特化的第二个参数格式正确,则选择它,正是因为它是特化,而不是主模板。

如果第二个模板参数格式正确,则SFINAE开始。特别是:

When substituting the explicitly specified or deduced type for the template parameter fails, the specialization is discarded from the overload set instead of causing a compile error.

The following type errors are SFINAE errors:

attempting to use a member of a type, where the type does not contain the specified member

这是如何完成的,即编译器究竟如何丢弃特化,而不是给出错误,没有具体说明;编译器只需要做正确的事情。

关于c++ - enable_if 如何帮助选择类模板的特化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62075258/

相关文章:

c++ - 为什么我的模板元代码比 for 循环慢?

c++ - 指定类模板参数的要求

c++ - 如何重写它以使其符合 C++ 标准

c++ - 我可以使用别名模板专门化一个类模板吗?

c++ - Typedef 相互引用的 STL 容器

C++ AVL对数组的顺序遍历

c++ - 是否需要 `void_t` 来检查类是否具有具有特定签名的方法?

c++ - void * 到运行时 std::tuple 的第 n 个元素

c++ - Karatsuba 整数乘法因段错误而失败

c++ - 如何重新使用 MySQL++ 查询对象来调用多个存储过程?