enable_if如何帮助选择类模板的专业化?
How does enable_if help select specializations of a class template?
我对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;
的声明时,它将看到两个可能的模板实例化:
- "主模板"
A<T, Enable>
其中T
是float
类型,启用是void
类型(因为默认值(。 - 特化
A<T, void>
其中T
是float
类型,void
是带有enable_if
的表达式的结果。
这些不是模棱两可吗? 两者都有效地导致A<T, void>
,那么为什么选择专业化呢?
在另一种情况下,如A<int> primary;
,编译器的选项似乎是:
- 主要的,
A<T, Enable>
,其中T
是int
类型,Enable
是void
类型。 - 专业化,
A<T, ?>
,其中T
是int
的类型,?
代表我完全迷失的地方。 在这种情况下,enable_if
条件为 false,因此它没有定义type
,这会给您留下A<int, typename >
. 这不是语法错误吗? 即使面对SFINAE?
来自关于类模板部分专用化的参考:
当类或变量(自 C++14 以来(模板实例化,并且存在部分专用化可用时,编译器必须决定是使用主模板还是其部分专用化之一。
如果只有一个专用化与模板参数匹配,则使用该专用化
在这种情况下,如果专业化的第二个参数格式正确,则选择它,正是因为它是专业化,而不是主要模板。
如果第二个模板参数的格式不正确,则 SFINAE 将启动。特别:
当将显式指定或推导的类型替换为模板参数失败时,将从重载集中丢弃专用化,而不是导致编译错误。
和
以下类型错误是 SFINAE 错误:
尝试使用某个类型的成员,其中 类型不包含指定的成员
如何做到这一点,即编译器如何准确地放弃专业化,而不是给出错误,没有指定;编译器只需要做正确的事情。
这些不是模棱两可吗?两者都有效地导致
A<T, void>
,那么为什么选择专业化呢?
否,专用化比主模板更专用,因为它要求void
第二个参数(假设enable_if
条件为 true(,而主模板不限制它。
专业化,
A<T, ?>
,其中T
是int
的类型,?
代表我完全迷失的地方。在这种情况下,enable_if
条件为 false,因此它不定义类型,这会给您留下A<int, typename >
.这不是语法错误吗?即使面对SFINAE?
没错,专业化中的第二个参数被证明是无效的。但这是一个"软"错误,SFINAE 检测到它并使编译器放弃专用化。(我不认为编译器会用空字符串文本替换enable_if_t<...>::type
然后分析A<int, typename >
;更有可能的是,一旦它注意到enable_if
缺乏::type
,它就会放弃专业化。
- 如何使用默认参数等选择模板专业化
- 如何(从固定列表中)选择一个数字序列,该序列将与目标数字相加
- 模板化建造师专业化
- 选择要调用的构造函数
- C++选择排序算法中的逻辑错误
- QTreeView幻灯片多选后无法使用单击选择
- 类模板的成员功能的定义在单独的TU中完全专业化
- 无法获取菜单选择以运行函数.C++
- Qt C++静态thread_local QNetworkAccessManager是线程应用程序的好选择吗
- 在C++中,如何通过几种类型从元组中选择多个元素
- 讨论 - 创建矩阵时的数组与向量的向量 - 什么是最实用的选择
- 对可变参数使用声明.如何选择正确的功能
- 选择选举获胜者的程序
- 部分专业化和嵌套模板
- enable_if如何帮助选择类模板的专业化?
- 为什么这个模板代码不选择部分专业化
- 为什么没有选择模板专业化?
- 使用声明类型选择函数专业化
- GCC 7 没有选择正确的类型特征专业化
- 是否可以使用std :: enable_if选择成员模板专业化