模棱两可的部分专业化取决于std :: enable_if
Ambiguous partial specialization depending on std::enable_if
我有以下代码:
#include <iostream>
template <class T, typename U = void> class A;
template <class T>
class C
{
public:
typedef T Var_t;
};
template <class T>
class B : public C<T>
{
};
template <class T>
class A<B<T>>
{
public:
A() { std::cout << "Here." << std::endl; }
};
template <class T>
class A<T, typename std::enable_if<
std::is_base_of<C<typename T::Var_t>, T>::value>
::type>
{
public:
A() { std::cout << "There." << std::endl;}
};
int main()
{
A<B<int>> a;
return 0;
}
编译器尝试使用参数B<int>
实例化第二部分专业化时,std::is_base_of<C<int>, B<int>>::value
为true
,因此std::enable_if<...>::type
返回void
(如果未指定默认类型)。这会导致"模棱两可的部分专业化"错误,因为编译器无法在第一部分和第二部分专业方面做出决定。到目前为止,一切都很好。但是,当我将std::enable_if
中的代码替换为true
(即第二部分专业化只是template <class T> class A<T, typename std::enable_if<true>::type>
)时,代码编译并运行。它输出"Here"
,表明选择了第一个专业化。
我的问题是:如果他们都对void
进行评估,为什么std::enable_if<true>::type
的行为与std::enable_if<std::is_base_of<...>::value>::type
的行为不同?
此行为已在此处的IDEONE上进行了测试和验证。
在std::enable_if<true>::type
中,您的代码定义了A类A的两个专业:
-
A<B<T>, void>
-
A<T, std::enable_if<true>::type>
。
这两个专业彼此之间完全不同。第一个专业化狭窄地集中在B<T>
型,而第二个专业化完全拟合了任何类型。同样,在第二个专业化中,std::enable_if
表达式不取决于T
。
对于任何声明A<X> a;
,X
类型将匹配B<something>
。如果与B<something>
匹配,则将使用第一个专业化,因为它是"更专业的"。如果X不匹配B<something>
,则将使用第二个更通用的专业化。无论哪种方式,您都不会遇到模棱两可的错误。
有关更多详细信息,请参见部分模板专业化中的部分顺序的讨论
现在让我们考虑std::enable_if<std::is_base_of<...>::value>::type
案例。
您仍然有两个专业化
-
A<B<T>, void>
-
A<T, std::enable_if<...>>
。
类型B<int>
现在匹配两个专业(一定程度)。显然,它与A<B<T>>, void>
专业化匹配,但也与A<T, std::enable_if...>>
专业化匹配,因为B<int>
是一种满足std::enable_if
表达式所施加的条件的类型。
为您提供两个同等有效的专业,这是您声明可变a
的候选人,因此您会得到"模棱两可的部分专业化"错误。
,如果您在main
中添加了另外两个声明,这可能会使所有这些都更具体。
A<C<int>> x;
A<int> y;
在std::enable_if<true>
情况下,这将编译,两个声明都将称为"那里"构造函数。
在更复杂的情况下,x
的声明将编译并调用"那里"构造函数,但y
的声明将会有一个编译器错误。
没有int::Var_t
,因此std::enable_if
表达式将替换失败,Sfinae将隐藏该专业化。这意味着不会有任何适合int
的专业化,您将获得错误aggregate ‘A<int> y’ has incomplete type and cannot be defined
- 我的简单if-else语句是如何无法访问的代码
- 如何将enable-if与模板参数和参数包一起使用
- 无论条件是否为true,if总是在c++中执行
- Arduino:for/while/if在void setup()或void loop()之前?——错误:之前需要不合格
- Insert函数不适用于2 if语句C++
- If语句未被求值C++
- C++嵌套if语句,基本货币交换
- 多个If语句与使用逻辑运算符计算条件的单个语句的比较
- 是否可以使用if constexpr删除控制流语句
- 要与"if constexpr"一起使用的编译时消息(在预处理器之后)
- 如何删除peer if else分支中的冗长句子
- 我似乎对if/else的基本语句有问题:/
- if数组上的随机数
- 将按位if条件转换为普通if条件
- If语句在c++中被忽略
- 比较if语句中的数组值和int值
- 使用if-else将数字转换为单词
- 为什么简单的算术减法在"if"条件下不起作用?
- 检查一个类型是否直接派生自"enable if"上下文中的另一个类型(是其子类型)
- SFINAE with boost enable if