我对 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;
的声明时,它将看到两个可能的模板实例化:
- “主模板”
A<T, Enable>
其中T
是类型float
Enable 是类型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
条件为假,所以它没有定义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/