17 Templates [temp]

17.3 Template arguments [temp.arg]

17.3.3 Template template arguments [temp.arg.template]

A template-argument для шаблона template-parameter должно быть именем шаблона класса или шаблона псевдонима, выраженным как id-expression. При template-argumentименовании шаблона класса учитываются только первичные шаблоны классов при сопоставлении аргумента шаблона шаблона с соответствующим параметром; частичные специализации не рассматриваются, даже если их списки параметров совпадают со списком параметров шаблона.

Любые partial specializations связанные с шаблоном первичного класса или шаблоном первичной переменной рассматриваются при создании template-parameter экземпляра специализации, основанной на шаблоне . Если специализация не видна в момент создания экземпляра и была бы выбрана, если бы была видима, программа имеет неправильный формат, диагностическая проверка не требуется. [Example:

template<class T> class A {     // primary template
  int x;
};
template<class T> class A<T*> { // partial specialization
  long x;
};
template<template<class U> class V> class C {
  V<int>  y;
  V<int*> z;
};
C<A> c;             // V<int> within C<A> uses the primary template, so c.y.x has type int
                    // V<int*> within C<A> uses the partial specialization, so c.z.x has type long

end example]

Соответствует template-argumentшаблону, template-parameter P если P он не менее специализирован, чем template-argument A. Если P содержит пакет параметров, то A также соответствует, P если каждый из Aпараметров шаблона совпадает с соответствующим параметром шаблона в template-parameter-listиз P. Два параметра шаблона совпадают, если они одного типа (тип, не тип, шаблон), для не-типа template-parametersих типы эквивалентны ([temp.over.link]), а для шаблона template-parameters, каждое из их соответствующих template-parameters совпадений, рекурсивно. Если P's template-parameter-listсодержит a template parameter pack, пакет параметров шаблона будет соответствовать нулю или более параметрам шаблона или пакетам параметров шаблона в template-parameter-listиз A с тем же типом и формой, что и пакет параметров шаблона в P (игнорируя, являются ли эти параметры шаблона пакетами параметров шаблона).

[Example:

template<class T> class A { /* ... */ };
template<class T, class U = T> class B { /* ... */ };
template<class ... Types> class C { /* ... */ };
template<auto n> class D { /* ... */ };
template<template<class> class P> class X { /* ... */ };
template<template<class ...> class Q> class Y { /* ... */ };
template<template<int> class R> class Z { /* ... */ };

X<A> xa;            // OK
X<B> xb;            // OK
X<C> xc;            // OK
Y<A> ya;            // OK
Y<B> yb;            // OK
Y<C> yc;            // OK
Z<D> zd;            // OK

end example]

[Example:

template <class T> struct eval;

template <template <class, class...> class TT, class T1, class... Rest>
struct eval<TT<T1, Rest...>> { };

template <class T1> struct A;
template <class T1, class T2> struct B;
template <int N> struct C;
template <class T1, int N> struct D;
template <class T1, class T2, int N = 17> struct E;

eval<A<int>> eA;            // OK: matches partial specialization of eval
eval<B<int, float>> eB;     // OK: matches partial specialization of eval
eval<C<17>> eC;             // error: C does not match TT in partial specialization
eval<D<int, 17>> eD;        // error: D does not match TT in partial specialization
eval<E<int, float>> eE;     // error: E does not match TT in partial specialization

end example]

Шаблон template-parameter P является, по крайней мере, таким же специализированным, как шаблон, template-argument A если, учитывая следующую перезапись двух шаблонов функций, шаблон функции, соответствующий, по P крайней мере, так же специализирован, как шаблон функции, соответствующий в A соответствии с partial ordering rules for function templates. Учитывая изобретенный шаблон класса X со списком параметров шаблона A (включая аргументы по умолчанию):

  • Каждый из двух шаблонов функций имеет те же параметры шаблона, что и P или A.

  • Каждый шаблон функции имеет один параметр функции, тип которого является специализацией X с аргументами шаблона, соответствующими параметрам шаблона из соответствующего шаблона функции, где для каждого параметра PP шаблона в списке параметров шаблона шаблона функции формируется соответствующий аргумент шаблона AA . Если PP объявляется пакет параметров, то AA это расширение пакета PP... ([temp.variadic]); в противном случае AA - это id-expression PP.

Если при перезаписи получается недопустимый тип, то P он не такой специализированный, как A.