为什么这些模板模糊? [英] Why are these templates ambiguous?

查看:144
本文介绍了为什么这些模板模糊?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这本书 C ++范本:完整指南的第275页有一个例子,



引用书中的摘录...

  template< typename T> 
class Promotion< T,T> {
public:
typdef T ResultT;
};

template< typename T1,typename T2>
class Promotion< Array< T1>,Array< T2> > {
public:
typedef Array< typename Promotion< T1,T2> :: ResultT> ResultT;
};

template< typename T>
class Promotion< Array< T>,Array< T> > {
public:
typedef Array< typename Promotion< T,T> :: ResultT> ResultT;
};不幸的是,部分专业化促销< Array< Array> ; T1>,阵列< T2> >
既不比部分专业化
促销< T,T> 为了避免模板选择模糊性,添加了最后一个部分
specialization。


前两个模板为什么含糊不清,以及为什么最后一个模板是否解决了模糊问题?当我尝试应用规则,我不能弄清楚它是如何出现的模糊,或者如果我认为我有一个方法,它发生我不知道为什么最后一个模板解决问题。

解决方案

也许你的困惑来自于关系比专业化。这是一个部分订单,而不是一个总订单 - 这意味着给定2模板专业化,并不总是一个比另一个更专业的情况。



Anon的意见是对的:假设第三个专业化不存在,后来在你的代码中你有:

  Promotion< Array< double>,Array< double> > foo; 

(当然你可能不会真正创建这个空结构体类型的变量,



给定 foo 的这个声明,前两个专业中的哪一个

$ <$ p


  • 专业化1适用于 T = Array< double>

  • 专业化2适用于 T1 = double T2 = double



两个专业都适用,因此我们需要确定哪一个比另一个更专业,并选择一个。怎么样?我们将说, X Y 更专业,如果至少如同< Y ,但 Y 不至少与 X 。虽然看起来这只是跳舞的问题,有一个聪明的规则,我们可以用来回答这个新的问题:



X 至少与 Y if一样专门,无论我们分配给 X ,结果类型总是可以与 Y 匹配。



注我们忘记了当前实例化中涉及的特定类型(在这种情况下, double ) - 至少与特殊化关系是部分



专业化1总是可以通过专业化2来匹配?这个过程有点像代数。我们要求任何类型 T ,我们可以找到 T1 T2 ,使得:

  Promotion< Array< T1& > = Promotion< T,T> 

这意味着:

  Array< T1> = T 
数组< T2> = T

因此答案是否定的。看看第一个隐含的结果,给定任何类型 T ,一般来说,不可能找到类型 T1 数组< T1> 是与 T 相同的类型。 (如果 T 碰巧是 Array< long> ,但如果 T int char * 或大多数其他类型。)



另一种方法呢?专业化2总是与专业化1相匹配?我们要求对于任何类型 T1 T2 ,我们可以找到一个类型 T ,使得:

 促销< T,T& = Promotion< Array< T1>,Array< T2> > 

显示:

 code> T = Array< T1> 
T = Array< T2>

所以答案是否定的。给定任何类型 T1 ,总是可以找到一个类型 T ,使 T 是与 Array 相同的类型 - 只是字面上设置 T = Array< T1> 。但一般来说,其他类型 T2 不限于与 T1 相同,如果不是 T1 = bool T2 = float ),那么将无法找到类型 Array< T1> Array< T2> 相同的所以一般来说,不可能找到这样的类型 T



在这种情况下,专业化比其他专业化,甚至都不如其他专业化。因此,如果需要实例化这个模板类,并且两个特殊化匹配,就像在Anon给出的例子中一样,没有办法选择一个最好的。


The book C++ Templates : The Complete Guide has an example on page 275 that I'm having trouble wrapping my head around.

Quoting excerpts from the book...

template <typename T>
class Promotion<T,T> {
  public:
    typdef T ResultT;
};

template<typename T1, typename T2>
class Promotion<Array<T1>, Array<T2> > {
  public:
    typedef Array<typename Promotion<T1,T2>::ResultT> ResultT;
};

template<typename T>
class Promotion<Array<T>, Array<T> > {
  public:
    typedef Array<typename Promotion<T,T>::ResultT> ResultT;
};

Unfortunately, the partial specialization Promotion<Array<T1>, Array<T2> > is neither more nor less specialized than the partial specialization Promotion<T,T>. To avoid template selection ambiguity, the last partial specialization was added. It is more specialized than either of the previous two partial specializations.

Why are the first two templates ambiguous, and why does the last template solve the ambiguity issue? When I try to apply the rules I either can't figure out how it comes up with an ambiguity, or if I think I have a way for it to happen I don't know why the last template solves the problem.

解决方案

Maybe your confusion stems from how the relation "is more specialised than" works. It's a partial order, not a total order -- that means that given 2 template specialisations, it's not always the case that one is more specialised than the other.

Anon's comment is right: Suppose that 3rd specialisation didn't exist, and later in your code you had:

Promotion<Array<double>, Array<double> > foo;

(Of course you probably wouldn't actually create a variable of this empty struct type, but this is just the simplest way to force its instantiation.)

Given this declaration of foo, which of the 1st 2 specialisations would be picked?

  • Specialisation 1 applies, with T = Array<double>.
  • Specialisation 2 applies, with T1 = double, T2 = double.

Both specialisations are applicable, so we need to determine which "is more specialised than" the other, and pick that one. How? We will say that X is more specialised than Y if it is at least as specialised as Y, but Y is not at least as specialised as X. Although it seems like this is just dancing around the problem, there is a clever rule that we can use to answer this new question:

X is at least as specialised as Y if, regardless of what types we assign to the template parameters of X, the resulting type could always be matched by Y.

Note that we forget about the particular types involved in the current instantiation (in this case, double) -- the "is at least as specialised as" relation is a property of the partial specialisations themselves, and doesn't depend on particular instantiations.

Can specialisation 1 always be matched by specialisation 2? The process is a bit like algebra. We require that for any type T, we can find types T1 and T2 such that:

Promotion<Array<T1>, Array<T2> > = Promotion<T, T>

This implies:

Array<T1> = T
Array<T2> = T

So the answer is no. Looking at just the first implied result, given any type T, in general it's not possible to find a type T1 such that Array<T1> is the same type as T. (It would work if T happened to be Array<long>, but not if T is int or char* or most other types.)

What about the other way around? Can specialisation 2 always be matched by specialisation 1? We require that for any types T1 and T2, we can find a type T such that:

Promotion<T, T> = Promotion<Array<T1>, Array<T2> >

Implying:

T = Array<T1>
T = Array<T2>

So the answer is again no. Given any type T1, it's always possible to find a type T such that T is the same type as Array<T1> -- just literally set T = Array<T1>. But in general the other type T2 is not constrained to be the same as T1, and if it's not (e.g. if T1 = bool but T2 = float) then it will not be possible to find a type T that is the same as both Array<T1> and Array<T2>. So in general, it's not possible to find such a type T.

In this case, not only is neither specialisation more specialised than the other, neither is even as specialised as the other. As a result, if the need arises to instantiate this template class and both specialisations match -- as it does in the example Anon gave -- there is no way to choose a "best" one.

这篇关于为什么这些模板模糊?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆