13 Templates [temp]

13.2 Template parameters [temp.param]

type-parameter-key:
class
typename
The component names of a type-constraint are its concept-name and those of its nested-name-specifier (if any).
[Note 1: 
The > token following the template-parameter-list of a type-parameter can be the product of replacing a >> token by two consecutive > tokens ([temp.names]).
— end note]
There is no semantic difference between class and typename in a type-parameter-key.
typename followed by an unqualified-id names a template type parameter.
typename followed by a qualified-id denotes the type in a non-type114 parameter-declaration.
[Example 1: class T { /* ... */ }; int i; template<class T, T i> void f(T t) { T t1 = i; // template-parameters T and i ::T t2 = ::i; // global namespace members T and i }
Here, the template f has a type-parameter called T, rather than an unnamed non-type template-parameter of class T.
— end example]
A template-parameter declaration shall not have a storage-class-specifier.
Types shall not be defined in a template-parameter declaration.
The identifier in a type-parameter is not looked up.
A type-parameter whose identifier does not follow an ellipsis defines its identifier to be a typedef-name (if declared without template) or template-name (if declared with template) in the scope of the template declaration.
[Note 2: 
A template argument can be a class template or alias template.
For example,
template<class T> class myarray { /* ... */ }; template<class K, class V, template<class T> class C = myarray> class Map { C<K> key; C<V> value; }; — end note]
A type-constraint Q that designates a concept C can be used to constrain a contextually-determined type or template type parameter pack T with a constraint-expression E defined as follows.
If Q is of the form C<A, , A>, then let E be C<T, A, , A>.
Otherwise, let E be C<T>.
If T is not a pack, then E is E, otherwise E is (E && ...).
The concept designated by a type-constraint shall be a type concept ([temp.concept]).
A type-parameter that starts with a type-constraint introduces the immediately-declared constraint of the type-constraint for the parameter.
[Example 2: template<typename T> concept C1 = true; template<typename... Ts> concept C2 = true; template<typename T, typename U> concept C3 = true; template<C1 T> struct s1; // associates C1<T> template<C1... T> struct s2; // associates (C1<T> && ...) template<C2... T> struct s3; // associates (C2<T> && ...) template<C3<int> T> struct s4; // associates C3<T, int> template<C3<int>... T> struct s5; // associates (C3<T, int> && ...) — end example]
A non-type template-parameter shall have one of the following (possibly cv-qualified) types:
The top-level cv-qualifiers on the template-parameter are ignored when determining its type.
A structural type is one of the following:
  • a scalar type, or
  • an lvalue reference type, or
  • a literal class type with the following properties:
    • all base classes and non-static data members are public and non-mutable and
    • the types of all bases classes and non-static data members are structural types or (possibly multidimensional) array thereof.
An id-expression naming a non-type template-parameter of class type T denotes a static storage duration object of type const T, known as a template parameter object, which is template-argument-equivalent ([temp.type]) to the corresponding template argument after it has been converted to the type of the template-parameter ([temp.arg.nontype]).
No two template parameter objects are template-argument-equivalent.
[Note 3: 
If an id-expression names a non-type non-reference template-parameter, then it is a prvalue if it has non-class type.
Otherwise, if it is of class type T, it is an lvalue and has type const T ([expr.prim.id.unqual]).
— end note]
[Example 3: using X = int; struct A {}; template<const X& x, int i, A a> void f() { i++; // error: change of template-parameter value &x; // OK &i; // error: address of non-reference template-parameter &a; // OK int& ri = i; // error: attempt to bind non-const reference to temporary const int& cri = i; // OK, const reference binds to temporary const A& ra = a; // OK, const reference binds to a template parameter object } — end example]
[Note 4: 
A non-type template-parameter cannot be declared to have type cv void.
[Example 4: template<void v> class X; // error template<void* pv> class Y; // OK — end example]
— end note]
A non-type template-parameter of type “array of T” or of function type T is adjusted to be of type “pointer to T.
[Example 5: template<int* a> struct R { /* ... */ }; template<int b[5]> struct S { /* ... */ }; int p; R<&p> w; // OK S<&p> x; // OK due to parameter adjustment int v[5]; R<v> y; // OK due to implicit argument conversion S<v> z; // OK due to both adjustment and conversion — end example]
A non-type template parameter declared with a type that contains a placeholder type with a type-constraint introduces the immediately-declared constraint of the type-constraint for the invented type corresponding to the placeholder ([dcl.fct]).
A default template argument is a template argument ([temp.arg]) specified after = in a template-parameter.
A default template argument may be specified for any kind of template-parameter (type, non-type, template) that is not a template parameter pack ([temp.variadic]).
A default template argument may be specified in a template declaration.
A default template argument shall not be specified in the template-parameter-lists of the definition of a member of a class template that appears outside of the member's class.
A default template argument shall not be specified in a friend class template declaration.
If a friend function template declaration D specifies a default template argument, that declaration shall be a definition and there shall be no other declaration of the function template which is reachable from D or from which D is reachable.
The set of default template arguments available for use is obtained by merging the default arguments from all prior declarations of the template in the same way default function arguments are ([dcl.fct.default]).
[Example 6: 
template<class T1, class T2 = int> class A; template<class T1 = int, class T2> class A; is equivalent to template<class T1 = int, class T2 = int> class A;
— end example]
If a template-parameter of a class template, variable template, or alias template has a default template argument, each subsequent template-parameter shall either have a default template argument supplied or be a template parameter pack.
If a template-parameter of a primary class template, primary variable template, or alias template is a template parameter pack, it shall be the last template-parameter.
A template parameter pack of a function template shall not be followed by another template parameter unless that template parameter can be deduced from the parameter-type-list ([dcl.fct]) of the function template or has a default argument ([temp.deduct]).
A template parameter of a deduction guide template ([temp.deduct.guide]) that does not have a default argument shall be deducible from the parameter-type-list of the deduction guide template.
[Example 7: template<class T1 = int, class T2> class B; // error // U can be neither deduced from the parameter-type-list nor specified template<class... T, class... U> void f() { } // error template<class... T, class U> void g() { } // error — end example]
When parsing a default template argument for a non-type template-parameter, the first non-nested > is taken as the end of the template-parameter-list rather than a greater-than operator.
[Example 8: template<int i = 3 > 4 > // syntax error class X { /* ... */ }; template<int i = (3 > 4) > // OK class Y { /* ... */ }; — end example]
A template-parameter of a template template-parameter is permitted to have a default template argument.
When such default arguments are specified, they apply to the template template-parameter in the scope of the template template-parameter.
[Example 9: template <template <class TT = float> class T> struct A { inline void f(); inline void g(); }; template <template <class TT> class T> void A<T>::f() { T<> t; // error: TT has no default template argument } template <template <class TT = char> class T> void A<T>::g() { T<> t; // OK, T<char> } — end example]
If a template-parameter is a type-parameter with an ellipsis prior to its optional identifier or is a parameter-declaration that declares a pack ([dcl.fct]), then the template-parameter is a template parameter pack.
A template parameter pack that is a parameter-declaration whose type contains one or more unexpanded packs is a pack expansion.
Similarly, a template parameter pack that is a type-parameter with a template-parameter-list containing one or more unexpanded packs is a pack expansion.
A type parameter pack with a type-constraint that contains an unexpanded parameter pack is a pack expansion.
A template parameter pack that is a pack expansion shall not expand a template parameter pack declared in the same template-parameter-list.
[Example 10: template <class... Types> // Types is a template type parameter pack class Tuple; // but not a pack expansion template <class T, int... Dims> // Dims is a non-type template parameter pack struct multi_array; // but not a pack expansion template <class... T> struct value_holder { template <T... Values> struct apply { }; // Values is a non-type template parameter pack }; // and a pack expansion template <class... T, T... Values> // error: Values expands template type parameter struct static_array; // pack T within the same template parameter list — end example]
114)114)
Since template template-parameters and template template-arguments are treated as types for descriptive purposes, the terms non-type parameter and non-type argument are used to refer to non-type, non-template parameters and arguments.