enable_if如何帮助选择类模板的特殊化?

问题描述 投票:0回答:1

我对SFINAE有基本的掌握,我想我明白很多例子中的 std::enable_if 利用它来选择函数模板的特殊性,但我很难理解它对类模板的作用。

下面的例子是来自 cppreference.com的解释。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也是如此?
c++ template-meta-programming template-specialization enable-if class-template
1个回答
1
投票

从参考文献中可以看到 部分专业化 的类模板。

当一个类或变量(自C++14以来)模板被实例化时,如果存在部分特化,编译器必须决定是使用主模板还是其部分特化之一。

如果只有一个特化符合模板参数,则使用该特化。

在这种情况下,如果特殊化的第2个论点形式良好,则选择它。正因为 它是一个特殊化,而不是主模板。

如果第2个模板参数是 匀称 SFINAE 踢到了。特别是:当将明确指定或推导的类型替换为模板参数失败时,会从重载集中抛弃特殊化。

当用显式指定的或推导的类型代替模板参数失败时,特殊化将从重载集中被丢弃。而不是造成编译错误.

以下类型错误是SFINAE错误。

试图使用一个类型的成员,而该类型不包含指定的成员。

如何做到这一点,即编译器到底如何抛弃这个特殊化,而不是给出一个错误,没有规定,只要求编译器做正确的事情。


1
投票

这些不是模棱两可吗?两者的结果实际上都是 A<T, void>,那为什么要选择这个专业呢?

不,专业是 更专业 比主模板要好,因为它要求第二个参数是 void (假设 enable_if 条件为真),而主模板并没有限制它。

的特殊化。A<T, ?>,其中 T 是类型 int? 代表着我完全迷失的地方。在这种情况下 enable_if 条件为false,所以它没有定义类型,这样你就有了 A<int, typename >. 这不是语法错误吗?即使面对SFINAE?

没错,特殊化中的第二个参数原来是无效的。但这是一个 "软 "错误,SFINAE会检测到这个错误,并使编译器放弃这个特殊化。(我不认为编译器会用文本替换掉那些 "软 "错误。enable_if_t<...>::type 用一个空字符串,然后分析 A<int, typename >它更有可能的是,一旦它发现缺少这种专门化,它就会放弃这种专门化。::typeenable_if.)

© www.soinside.com 2019 - 2024. All rights reserved.