[temp.param]

# 13 Templates [[temp]](./#temp)

## 13.2 Template parameters [temp.param]

[1](#1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L234)

The syntax for[*template-parameter*](#nt:template-parameter "13.2 Template parameters [temp.param]")*s* is:

[template-parameter:](#nt:template-parameter "13.2 Template parameters [temp.param]")  
[*type-parameter*](#nt:type-parameter "13.2 Template parameters [temp.param]")  
[*parameter-declaration*](dcl.fct#nt:parameter-declaration "9.3.4.6 Functions [dcl.fct]")  
[*type-tt-parameter*](#nt:type-tt-parameter "13.2 Template parameters [temp.param]")  
[*variable-tt-parameter*](#nt:variable-tt-parameter "13.2 Template parameters [temp.param]")  
[*concept-tt-parameter*](#nt:concept-tt-parameter "13.2 Template parameters [temp.param]")

[type-parameter:](#nt:type-parameter "13.2 Template parameters [temp.param]")  
[*type-parameter-key*](#nt:type-parameter-key "13.2 Template parameters [temp.param]") ...opt [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]")opt  
[*type-parameter-key*](#nt:type-parameter-key "13.2 Template parameters [temp.param]") [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]")opt = [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]")  
[*type-constraint*](#nt:type-constraint "13.2 Template parameters [temp.param]") ...opt [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]")opt  
[*type-constraint*](#nt:type-constraint "13.2 Template parameters [temp.param]") [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]")opt = [*type-id*](dcl.name#nt:type-id "9.3.2 Type names [dcl.name]")

[type-parameter-key:](#nt:type-parameter-key "13.2 Template parameters [temp.param]")  
class  
typename

[type-constraint:](#nt:type-constraint "13.2 Template parameters [temp.param]")  
[*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]")opt [*concept-name*](temp.concept#nt:concept-name "13.7.9 Concept definitions [temp.concept]")  
[*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]")opt [*concept-name*](temp.concept#nt:concept-name "13.7.9 Concept definitions [temp.concept]") < [*template-argument-list*](temp.names#nt:template-argument-list "13.3 Names of template specializations [temp.names]")opt >

[type-tt-parameter:](#nt:type-tt-parameter "13.2 Template parameters [temp.param]")  
[*template-head*](temp.pre#nt:template-head "13.1 Preamble [temp.pre]") [*type-parameter-key*](#nt:type-parameter-key "13.2 Template parameters [temp.param]") ...opt [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]")opt  
[*template-head*](temp.pre#nt:template-head "13.1 Preamble [temp.pre]") [*type-parameter-key*](#nt:type-parameter-key "13.2 Template parameters [temp.param]") [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]")opt [*type-tt-parameter-default*](#nt:type-tt-parameter-default "13.2 Template parameters [temp.param]")

[type-tt-parameter-default:](#nt:type-tt-parameter-default "13.2 Template parameters [temp.param]")  
= [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]")opt [*template-name*](temp.names#nt:template-name "13.3 Names of template specializations [temp.names]")  
= [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") template [*template-name*](temp.names#nt:template-name "13.3 Names of template specializations [temp.names]")

[variable-tt-parameter:](#nt:variable-tt-parameter "13.2 Template parameters [temp.param]")  
[*template-head*](temp.pre#nt:template-head "13.1 Preamble [temp.pre]") auto ...opt [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]")opt  
[*template-head*](temp.pre#nt:template-head "13.1 Preamble [temp.pre]") auto [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]")opt = [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]")opt [*template-name*](temp.names#nt:template-name "13.3 Names of template specializations [temp.names]")

[concept-tt-parameter:](#nt:concept-tt-parameter "13.2 Template parameters [temp.param]")  
template < [*template-parameter-list*](temp.pre#nt:template-parameter-list "13.1 Preamble [temp.pre]") > concept ...opt [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]")opt  
template < [*template-parameter-list*](temp.pre#nt:template-parameter-list "13.1 Preamble [temp.pre]") > concept [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]")opt = [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]")opt [*template-name*](temp.names#nt:template-name "13.3 Names of template specializations [temp.names]")

The component names of a [*type-constraint*](#nt:type-constraint "13.2 Template parameters [temp.param]") are
its [*concept-name*](temp.concept#nt:concept-name "13.7.9 Concept definitions [temp.concept]") and
those of its [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") (if any)[.](#1.sentence-2)

[*Note [1](#note-1)*:

The > token following the[*template-parameter-list*](temp.pre#nt:template-parameter-list "13.1 Preamble [temp.pre]") of a[*type-tt-parameter*](#nt:type-tt-parameter "13.2 Template parameters [temp.param]"),[*variable-tt-parameter*](#nt:variable-tt-parameter "13.2 Template parameters [temp.param]"), or[*concept-tt-parameter*](#nt:concept-tt-parameter "13.2 Template parameters [temp.param]") can be the product of replacing a>> token by two consecutive > tokens ([[temp.names]](temp.names "13.3 Names of template specializations"))[.](#1.sentence-3)

â *end note*]

[2](#2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L306)

A template parameter is of one of the following kinds:

- [(2.1)](#2.1)

  A [*type template parameter*](#def:template_parameter,type "13.2 Template parameters [temp.param]") is
a template parameter introduced by a [*type-parameter*](#nt:type-parameter "13.2 Template parameters [temp.param]")[.](#2.1.sentence-1)

- [(2.2)](#2.2)

  A [*constant template parameter*](#def:template_parameter,constant "13.2 Template parameters [temp.param]") is
a template parameter introduced by a [*parameter-declaration*](dcl.fct#nt:parameter-declaration "9.3.4.6 Functions [dcl.fct]")[.](#2.2.sentence-1)

- [(2.3)](#2.3)

  A [*type template template parameter*](#def:template_parameter,type_template "13.2 Template parameters [temp.param]") is
a template parameter introduced by a [*type-tt-parameter*](#nt:type-tt-parameter "13.2 Template parameters [temp.param]")[.](#2.3.sentence-1)

- [(2.4)](#2.4)

  A [*variable template template parameter*](#def:template_parameter,variable_template "13.2 Template parameters [temp.param]") is
a template parameter introduced by a [*variable-tt-parameter*](#nt:variable-tt-parameter "13.2 Template parameters [temp.param]")[.](#2.4.sentence-1)

- [(2.5)](#2.5)

  A [*concept template parameter*](#def:template_parameter,concept "13.2 Template parameters [temp.param]") is
a template parameter introduced by a [*concept-tt-parameter*](#nt:concept-tt-parameter "13.2 Template parameters [temp.param]")[.](#2.5.sentence-1)

[3](#3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L329)

Type template template parameters,
variable template template parameters, and
concept template parameters
are collectively referred to as [*template template parameters*](#def:template_parameters,template "13.2 Template parameters [temp.param]")[.](#3.sentence-1)

[4](#4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L335)

The [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") of a [*type-constraint*](#nt:type-constraint "13.2 Template parameters [temp.param]"),
if any, shall not be dependent[.](#4.sentence-1)

[5](#5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L339)

A concept template parameter shall not have
associated constraints ([[temp.constr.decl]](temp.constr.decl "13.5.3 Constrained declarations"))[.](#5.sentence-1)

[6](#6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L343)

If a [*template-parameter*](#nt:template-parameter "13.2 Template parameters [temp.param]") is
a [*parameter-declaration*](dcl.fct#nt:parameter-declaration "9.3.4.6 Functions [dcl.fct]") that declares a pack ([[dcl.fct]](dcl.fct "9.3.4.6 Functions")), or
otherwise has an ellipsis prior to its optional [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]"),
then the [*template-parameter*](#nt:template-parameter "13.2 Template parameters [temp.param]") declares a template parameter pack ([[temp.variadic]](temp.variadic "13.7.4 Variadic templates"))[.](#6.sentence-1)

A template parameter pack that is a [*parameter-declaration*](dcl.fct#nt:parameter-declaration "9.3.4.6 Functions [dcl.fct]") whose type
contains one or more unexpanded packs is a pack expansion[.](#6.sentence-2)

Similarly,
a template parameter pack that is a template template parameter with a[*template-parameter-list*](temp.pre#nt:template-parameter-list "13.1 Preamble [temp.pre]") containing one or more unexpanded
packs is a pack expansion[.](#6.sentence-3)

A type parameter pack with a [*type-constraint*](#nt:type-constraint "13.2 Template parameters [temp.param]") that
contains an unexpanded parameter pack is a pack expansion[.](#6.sentence-4)

A template parameter pack that is a pack
expansion shall not expand a template parameter pack declared in the same[*template-parameter-list*](temp.pre#nt:template-parameter-list "13.1 Preamble [temp.pre]")[.](#6.sentence-5)

[*Example [1](#example-1)*: template <class... Types> // Types is a template type parameter packclass Tuple; // but not a pack expansiontemplate <class T, int... Dims> // Dims is a constant template parameter packstruct multi_array; // but not a pack expansiontemplate <class... T>struct value_holder {template <T... Values> struct apply { }; // Values is a constant template parameter pack}; // and a pack expansiontemplate <class... T, T... Values> // error: Values expands template type parameterstruct static_array; // pack T within the same template parameter list â *end example*]

[7](#7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L377)

There is no semantic difference betweenclass andtypename in a[*type-parameter-key*](#nt:type-parameter-key "13.2 Template parameters [temp.param]")[.](#7.sentence-1)

typename followed by an[*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2 Unqualified names [expr.prim.id.unqual]") names a template type parameter[.](#7.sentence-2)

typename followed by a[*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") denotes the type in a[*parameter-declaration*](dcl.fct#nt:parameter-declaration "9.3.4.6 Functions [dcl.fct]")[.](#7.sentence-3)

A [*template-parameter*](#nt:template-parameter "13.2 Template parameters [temp.param]") of the formclass [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") is a [*type-parameter*](#nt:type-parameter "13.2 Template parameters [temp.param]")[.](#7.sentence-4)

[*Example [2](#example-2)*: 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 template parameter
called T, rather than an unnamed constant
template parameter of class T[.](#7.sentence-5)

â *end example*]

The [*parameter-declaration*](dcl.fct#nt:parameter-declaration "9.3.4.6 Functions [dcl.fct]") of a [*template-parameter*](#nt:template-parameter "13.2 Template parameters [temp.param]") shall not have a [*storage-class-specifier*](dcl.stc#nt:storage-class-specifier "9.2.2 Storage class specifiers [dcl.stc]")[.](#7.sentence-6)

Types shall not be defined in a template parameter
declaration[.](#7.sentence-7)

[8](#8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L414)

The [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") in
a [*template-parameter*](#nt:template-parameter "13.2 Template parameters [temp.param]") denoting a type or template
is not looked up[.](#8.sentence-1)

An [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") that does not follow an ellipsis
is defined to be

- [(8.1)](#8.1)

a [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]") for a [*type-parameter*](#nt:type-parameter "13.2 Template parameters [temp.param]"),

- [(8.2)](#8.2)

a [*template-name*](temp.names#nt:template-name "13.3 Names of template specializations [temp.names]") for a [*variable-tt-parameter*](#nt:variable-tt-parameter "13.2 Template parameters [temp.param]"),

- [(8.3)](#8.3)

a [*template-name*](temp.names#nt:template-name "13.3 Names of template specializations [temp.names]") for a [*type-tt-parameter*](#nt:type-tt-parameter "13.2 Template parameters [temp.param]"), or

- [(8.4)](#8.4)

a [*concept-name*](temp.concept#nt:concept-name "13.7.9 Concept definitions [temp.concept]") for a [*concept-tt-parameter*](#nt:concept-tt-parameter "13.2 Template parameters [temp.param]"),

in the scope of the template declaration[.](#8.sentence-2)

[9](#9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L432)

A [*type-constraint*](#nt:type-constraint "13.2 Template parameters [temp.param]") 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*](temp.constr.decl#nt:constraint-expression "13.5.3 Constrained declarations [temp.constr.decl]") E defined as follows[.](#9.sentence-1)

If Q is of the form C<A1, …, An>,
then let Eâ² be C<T, A1, …, An>[.](#9.sentence-2)

Otherwise, let Eâ² be C<T>[.](#9.sentence-3)

If T is not a pack,
then E is Eâ²,
otherwise E is (Eâ² && ...)[.](#9.sentence-4)

This [*constraint-expression*](temp.constr.decl#nt:constraint-expression "13.5.3 Constrained declarations [temp.constr.decl]") E is called the[*immediately-declared constraint*](#def:constraint,immediately-declared "13.2 Template parameters [temp.param]") of Q for T[.](#9.sentence-5)

The concept designated by a [*type-constraint*](#nt:type-constraint "13.2 Template parameters [temp.param]") shall be a type concept ([[temp.concept]](temp.concept "13.7.9 Concept definitions"))[.](#9.sentence-6)

[10](#10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L449)

A [*type-parameter*](#nt:type-parameter "13.2 Template parameters [temp.param]") that starts with a [*type-constraint*](#nt:type-constraint "13.2 Template parameters [temp.param]") introduces the immediately-declared constraint
of the [*type-constraint*](#nt:type-constraint "13.2 Template parameters [temp.param]") for the parameter[.](#10.sentence-1)

[*Example [3](#example-3)*: 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*]

[11](#11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L467)

A constant template parameter
shall have one of the following (possibly cv-qualified) types:

- [(11.1)](#11.1)

a structural type (see below),

- [(11.2)](#11.2)

a type that contains a placeholder type ([[dcl.spec.auto]](dcl.spec.auto "9.2.9.7 Placeholder type specifiers")), or

- [(11.3)](#11.3)

a placeholder for a deduced class type ([[dcl.type.class.deduct]](dcl.type.class.deduct "9.2.9.8 Deduced class template specialization types"))[.](#11.sentence-1)

The top-level[*cv-qualifier*](dcl.decl.general#nt:cv-qualifier "9.3.1 General [dcl.decl.general]")*s* on the[*template-parameter*](#nt:template-parameter "13.2 Template parameters [temp.param]") are ignored when determining its type[.](#11.sentence-2)

[12](#12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L481)

A [*structural type*](#def:type,structural "13.2 Template parameters [temp.param]") is one of the following:

- [(12.1)](#12.1)

a scalar type, or

- [(12.2)](#12.2)

an lvalue reference type, or

- [(12.3)](#12.3)

a literal class type with the following properties:
  * [(12.3.1)](#12.3.1)

all base classes and non-static data members are public and non-mutable and

  * [(12.3.2)](#12.3.2)

the types of all base classes and non-static data members are
structural types or (possibly multidimensional) arrays thereof[.](#12.sentence-1)

[13](#13)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L497)

An [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") naming
a constant template parameter of class type T denotes a static storage duration object of type const T,
known as a [*template parameter object*](#def:template_parameter_object "13.2 Template parameters [temp.param]"),
which is template-argument-equivalent ([[temp.type]](temp.type "13.6 Type equivalence")) to
the corresponding template argument
after it has been converted
to the type of the template parameter ([[temp.arg.nontype]](temp.arg.nontype "13.4.3 Constant template arguments"))[.](#13.sentence-1)

No two template parameter objects are template-argument-equivalent[.](#13.sentence-2)

[*Note [2](#note-2)*:

If an [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") names
a non-reference constant template parameter,
then it is a prvalue if it has non-class type[.](#13.sentence-3)

Otherwise, if it is of class type T,
it is an lvalue and has type const T ([[expr.prim.id.unqual]](expr.prim.id.unqual "7.5.5.2 Unqualified names"))[.](#13.sentence-4)

â *end note*]

[*Example [4](#example-4)*: 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; // OKint& ri = i; // error: attempt to bind non-const reference to temporaryconst int& cri = i; // OK, const reference binds to temporaryconst A& ra = a; // OK, const reference binds to a template parameter object} â *end example*]

[14](#14)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L531)

[*Note [3](#note-3)*:

A constant template parameter
cannot be declared to have type cv void[.](#14.sentence-1)

[*Example [5](#example-5)*: template<void v> class X; // errortemplate<void* pv> class Y; // OK â *end example*]

â *end note*]

[15](#15)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L543)

A constant template parameterof type âarray of Tâ orof function type T is adjusted to be of type âpointer to Tâ[.](#15.sentence-1)

[*Example [6](#example-6)*: template<int* a> struct R { /* ... */ };template<int b[5]> struct S { /* ... */ };int p;
R<&p> w; // OK S<&p> x; // OK due to parameter adjustmentint v[5];
R<v> y; // OK due to implicit argument conversion S<v> z; // OK due to both adjustment and conversion â *end example*]

[16](#16)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L563)

A constant template parameter declared with a type that
contains a placeholder type with a [*type-constraint*](#nt:type-constraint "13.2 Template parameters [temp.param]") introduces the immediately-declared constraint
of the [*type-constraint*](#nt:type-constraint "13.2 Template parameters [temp.param]") for the invented type corresponding to the placeholder ([[dcl.fct]](dcl.fct "9.3.4.6 Functions"))[.](#16.sentence-1)

[17](#17)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L570)

A [*default template argument*](#def:template_argument,default "13.2 Template parameters [temp.param]") is
a template argument ([[temp.arg]](temp.arg "13.4 Template arguments")) specified after = in a [*template-parameter*](#nt:template-parameter "13.2 Template parameters [temp.param]")[.](#17.sentence-1)

A default template argument may be specified for
any kind of template parameter
that is not a template parameter pack ([[temp.variadic]](temp.variadic "13.7.4 Variadic templates"))[.](#17.sentence-2)

A default template argument may be specified in a template declaration[.](#17.sentence-3)

A default template argument shall not be specified in
the [*template-parameter-list*](temp.pre#nt:template-parameter-list "13.1 Preamble [temp.pre]")*s* of the definition of a member of a class template
that appears outside of the member's class[.](#17.sentence-4)

A default template argument
shall not be specified in a friend class template declaration[.](#17.sentence-5)

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[.](#17.sentence-6)

[18](#18)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L590)

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]](dcl.fct.default "9.3.4.7 Default arguments"))[.](#18.sentence-1)

[*Example [7](#example-7)*:

template<class T1, class T2 = int> class A;template<class T1 = int, class T2> class A; is equivalent totemplate<class T1 = int, class T2 = int> class A;

â *end example*]

[19](#19)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L606)

If a [*template-parameter*](#nt:template-parameter "13.2 Template parameters [temp.param]") of a class template, variable template, or alias template has
a default template argument,
each subsequent [*template-parameter*](#nt:template-parameter "13.2 Template parameters [temp.param]") shall either have a default template argument supplied or
declare a template parameter pack[.](#19.sentence-1)

If a [*template-parameter*](#nt:template-parameter "13.2 Template parameters [temp.param]") of
a primary class template, primary variable template, or alias template
declares a template parameter pack,
it shall be the last [*template-parameter*](#nt:template-parameter "13.2 Template parameters [temp.param]")[.](#19.sentence-2)

If a [*template-parameter*](#nt:template-parameter "13.2 Template parameters [temp.param]") of a function template
declares a template parameter pack, it
shall not be followed by another [*template-parameter*](#nt:template-parameter "13.2 Template parameters [temp.param]") unless that template parameter is deducible from the
parameter-type-list ([[dcl.fct]](dcl.fct "9.3.4.6 Functions")) of the function template or
has a default argument ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction"))[.](#19.sentence-3)

A template parameter of a deduction guide template ([[temp.deduct.guide]](temp.deduct.guide "13.7.2.3 Deduction guides"))
that does not have a default argument shall be deducible
from the parameter-type-list of the deduction guide template[.](#19.sentence-4)

[*Example [8](#example-8)*: template<class T1 = int, class T2> class B; // error// U can be neither deduced from the parameter-type-list nor specifiedtemplate<class... T, class... U> void f() { } // errortemplate<class... T, class U> void g() { } // error â *end example*]

[20](#20)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L637)

When parsing a default template argument
for a constant template parameter,
the first non-nested > is taken as
the end of the [*template-parameter-list*](temp.pre#nt:template-parameter-list "13.1 Preamble [temp.pre]") rather than a greater-than operator[.](#20.sentence-1)

[*Example [9](#example-9)*: template<int i = 3 > 4 > // syntax errorclass X { /* ... */ };

template<int i = (3 > 4) > // OKclass Y { /* ... */ }; â *end example*]

[21](#21)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L653)

A [*template-parameter*](#nt:template-parameter "13.2 Template parameters [temp.param]") of
a template [*template-parameter*](#nt:template-parameter "13.2 Template parameters [temp.param]") is permitted to have a default template argument[.](#21.sentence-1)

When such default arguments are specified,
they apply to the template [*template-parameter*](#nt:template-parameter "13.2 Template parameters [temp.param]") in the scope of the template [*template-parameter*](#nt:template-parameter "13.2 Template parameters [temp.param]")[.](#21.sentence-2)

[*Example [10](#example-10)*: 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*]

The associated constraints of a template template parameter
shall not contain a concept-dependent constraint ([[temp.constr.concept]](temp.constr.concept "13.5.2.4 Concept-dependent constraints"))[.](#21.sentence-3)

[*Example [11](#example-11)*: template<template<typename> concept C, template<C> class TT // error: C forms a concept-dependent constraint>struct A {}; â *end example*]
