[temp.arg.template] (original) (raw)
13 Templates [temp]
13.4 Template arguments [temp.arg]
13.4.4 Template template arguments [temp.arg.template]
Atemplate-argumentfor a template template parameter shall be the name of a template.
For a type-tt-parameter, the name shall denote a class template or alias template.
Only primary 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 ([temp.spec.partial]) associated with the primary template are considered when a specialization based on the template template parameter is instantiated.
If a specialization is not reachable from the point of instantiation, and it would have been selected had it been reachable, 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_]
A template template parameter P and a template-argument A arecompatibleif
- A denotes a class template or an alias template andP is a type template parameter,
- A denotes a variable template andP is a variable template parameter, or
- A denotes a concept andP is a concept template parameter.
A template template-argument A matches a template template parameter P whenA and P are compatible andP is at least as specialized as A, ignoring constraints on A if P is unconstrained.
If P contains a template parameter pack, then A also matches Pif each of A's template parameters matches the corresponding template parameter declared in thetemplate-head of P.
Two template parameters match if they are of the same kind, for constant template parameters, their types are equivalent ([temp.over.link]), and for template template parameters, each of their corresponding template parameters matches, recursively.
When P's template-head contains a template-parameterthat declares a template parameter pack ([temp.variadic]), the template parameter pack will match zero or more template parameters or template parameter packs declared in the template-head ofA with the same type and form as the template parameter pack declared 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):
- Each of the two function templates has the same template parameters and requires-clause (if any), respectively, as P or A.
- Each function template has a single function parameter whose type is a specialization of Xwith template arguments corresponding to the template parameters from the respective function template where, for each template-parameter PPin the template-head of the function template, a corresponding template-argument AA is formed.
If PP declares a template parameter pack, then AA is the pack expansion PP... ([temp.variadic]); otherwise, AA is an id-expression denoting PP.
If the rewrite produces an invalid type, then P is not at least as specialized as A.