Why are these patterns ambiguous?

The book C ++ Templates: The Complete Guide provides an example on page 275 that I am having trouble wrapping my head.

Quotes from an excerpt 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, partial specialization is Promotion<Array<T1>, Array<T2> >neither more nor less specialized than partial specialization Promotion<T,T>. To avoid ambiguity in choosing a template, the last partial specialization has been added. He is more specialized than any of the previous two partial specializations.

? , , , , , , .

+5
5

, , " " . , - , , , .

: , 3- , :

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

(, , , , .)

foo, 1- 2 ?

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

, , " , " , . ? , X , Y, Y, Y , , , X. , , , , :

X , Y, , , X, Y.

, , ( , double) - " , " .

1 2? . , T T1 T2 , :

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

:

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

, - . , T, T1 , Array<T1> , T. ( , T Array<long>, T int char* .)

? 2 1? , T1 T2 T , :

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

:

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

, . T1 T , T , Array<T1> - T = Array<T1>. T2 , T1, (, T1 = bool, T2 = float), T, , Array<T1> Array<T2>. T.

, , . , , - , , - "".

+14

, , .

Promotion< Array<S>, Array<S> >.

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

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

, , , . , .

( Array<T1>, - ), .

, , [temp.deduct.partial] , . 14.8.2.4 n3225 .

+3

j_random_hacker , :

template< class T >
class Array {};

template< class T1, class T2 >
class Promotion {};

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

template<typename T1, typename T2>      // b
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;
// };


//---------------------------- §14.5.4.2/1:

template< class T >
void a_( Promotion< T, T > );                      // a

template< class T1, class T2 >
void b_( Promotion< Array< T1 >, Array< T2 > > );  // b


//---------------------------- §14.5.5.2/3:

class aT {};
class bT1 {};
class bT2 {};

void a( Promotion< aT, aT > );                          // a
void b( Promotion< Array< bT1 >, Array< bT2 > > );      // b

void test()
{
    // Check if the concrete 'a' arguments fit also 'b':
    b_( Promotion< aT, aT >() );
    // Fails, so a is not at least as specialized as b

    // Check if the concrete 'b' arguments fit also 'a':
    a_( Promotion< Array< bT1 >, Array< bT2 > >() );
    // Fails, so b is not at least as specialized as a
}    

: .

, Someone Else & trade; , , , .

hth.,

+3

- , , . . , ++ , .

+2

, .

: " , , T1 T2 ".

: " , , T1 T2 Array".

, ... T1 T2 . ? , , .

, : " , , T1 T2 Array".

+2

All Articles