[英]How to resolve this ambiguity?
In the following code: 在以下代码中:
template <int...> struct IndexSequence {};
template <int, int, typename, int...> struct Helper;
template <int Start, typename Coefficients, int... Is>
struct Helper<Start, Start, Coefficients, Is...> {
using type = IndexSequence<Is...>;
};
template <int Start, int N, int... As, int... Is>
struct Helper<Start, N, IndexSequence<As...>, Is...> :
Helper<Start, N-1, IndexSequence<As...>, N-1, Is...> {};
int main() {
Helper<2,5, IndexSequence<1,2,3>>::type a;
}
I get the compile error: 我收到编译错误:
ambiguous class template instantiation for 'struct Helper<2, 2, IndexSequence<1, 2, 3>, 2, 3, 4>'
I figured it would resolve to the specialization 我认为它将解决专业化问题
template <int Start, typename Coefficients, int... Is>
struct Helper<Start, Start, Coefficients, Is...> {
using type = IndexSequence<Is...>;
};
But I guess it is also reading 但我想它也在阅读
struct Helper<Start, N, IndexSequence<As...>, Is...> :
Helper<Start, N-1, IndexSequence<As...>, N-1, Is...> {};
So how to resolve this ambiguity? 那么如何解决这种歧义呢?
The problem is essentially that none of the specializations is more specialized than the other. 问题基本上是没有一个专业化比另一个专业化更专业化。
When deciding which partial specialization too choose, the specializations are first matched against the arguments to check whether they are viable (here, both are). 在决定哪个部分特化也选择时,首先将特化与参数匹配以检查它们是否可行(这里两者都是)。 If multiple are viable, then to decide which one is to be chosen we have to check which one is more specialized than all others.
如果多个是可行的,那么要决定选择哪一个,我们必须检查哪一个比其他所有更专业。 This process is called "partial ordering" and done by comparing the specialized template "arguments" which each other (ie the template arguments in
Helper<...>
) - one template is taken as the argument template, and the other is the parameter template. 这个过程称为“部分排序”,通过比较彼此的专用模板“参数”(即
Helper<...>
的模板参数)来完成 - 一个模板作为参数模板,另一个是参数模板。 The argument template provides the types, and deduction is performed to see if the template parameters from the parameter template can be deduced given the argument template's types. 参数模板提供类型,并且执行演绎以查看是否可以在给定参数模板的类型的情况下推导出参数模板中的模板参数。
template <int Start, typename Coefficients, int... Is>
struct Helper<Start, Start, Coefficients, Is...>
// ^^^^^ ^^^^^ ^^^^^^^^^^^^ ^^^^^
// A: 1 2 3 4
template <int Start, int N, int... As, int... Is>
struct Helper<Start, N, IndexSequence<As...>, Is...>
// ^^^^^ ^ ^^^^^^^^^^^^^^^^^^^^ ^^^^^
// B: 1 2 3 4
For each argument of the argument template, some unique value is made up for each template parameter and substituted into the argument. 对于参数模板的每个参数,为每个模板参数组成一些唯一值并将其替换为参数。 These transformed arguments are then passed to the parameter template to check whether deduction succeeds or fails.
然后将这些转换后的参数传递给参数模板,以检查推导是成功还是失败。 As an example:
举个例子:
int
can be deduced from int
) int
可以从int
推导出来) Let's now look at the crucial deductions: 现在让我们来看看关键的推论:
B2 is deduced against A2, but as we used unique values for both Start
and N
, Start
in template A is deduced inconsistently , which means that deduction fails here. B2是根据A2推导出来的, 但由于我们对
Start
和N
使用了唯一值,因此模板A中的Start
不一致地推导出来 ,这意味着此处的推断失败。
A3 is deduced against B3, but since Coefficients
is some unique type (not a specialization of IndexSequence
!), deduction fails again. A3是根据B3推导出来的,但由于
Coefficients
是一些独特的类型(不是IndexSequence
!的特化),因此扣除再次失败。
Deduction failed at least once in both directions: Thus no template is in its entirety more specialized than the other. 扣除在两个方向上至少失败一次:因此,没有一个模板完全比另一个更专业。
Solve this partial ordering ambiguity by eg writing the first specialization as 通过例如将第一个特化作为编写来解决这种部分排序歧义
template <int Start, int... As, int... Is>
struct Helper<Start, Start, IndexSequence<As...>, Is...> {
using type = IndexSequence<Is...>;
};
Now, the second deduction that failed above doesn't fail anymore. 现在,上面失败的第二次扣除不再失败。 Only the one that took specialization B as the argument template.
只有将专业化B作为参数模板的那个。 That means that B is more specialized, and thus selected.
这意味着B更专业,因此被选中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.