[temp.arg.template] (original) (raw)

13 Templates [temp]

13.4 Template arguments [temp.arg]

13.4.4 Template template arguments [temp.arg.template]

When the template-argument names a class template, only primary class templates are considered when matching the template template argument with the corresponding parameter; partial specializations are not considered even if their parameter lists match that of the template template parameter.

Any partial specializations associated with the primary class template or primary variable template are considered when a specialization based on the templatetemplate-parameteris instantiated.

If a specialization is not visible at the point of instantiation, and it would have been selected had it been visible, the program is ill-formed, no diagnostic required.

[Example 1: template<class T> class A { int x;};template<class T> class A<T*> { long x;};template<template<class U> class V> class C { V<int> y; V<int*> z;}; C<A> c; — _end example_]

In this comparison, if P is unconstrained, the constraints on A are not considered.

If P contains a template parameter pack, then A also matches Pif each of A's template parameters matches the corresponding template parameter in thetemplate-head of P.

When P's template-head contains a template parameter pack ([temp.variadic]), the template parameter pack will match zero or more template parameters or template parameter packs in the template-head ofA with the same type and form as the template parameter pack in P(ignoring whether those template parameters are template parameter packs).

[Example 2: 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; X<B> xb; X<C> xc; Y<A> ya; Y<B> yb; Y<C> yc; Z<D> zd; — _end example_]

[Example 3: 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; eval<B<int, float>> eB; eval<C<17>> eC; eval<D<int, 17>> eD; eval<E<int, float>> eE; — _end example_]

[Example 4: template<typename T> concept C = requires (T t) { t.f(); };template<typename T> concept D = C<T> && requires (T t) { t.g(); };template<template<C> class P> struct S { };template<C> struct X { };template<D> struct Y { };template<typename T> struct Z { }; S<X> s1; S<Y> s2; S<Z> s3; — _end example_]

A template template-parameter P is at least as specialized as a template template-argument Aif, given the following rewrite to two function templates, the function template corresponding to Pis at least as specialized as the function template corresponding to Aaccording to the partial ordering rules for function templates.

Given an invented class template Xwith the template-head of A (including default arguments and requires-clause, if any):

If the rewrite produces an invalid type, then P is not at least as specialized as A.