Files
cppdraft_translate/cppdraft/temp/param.md
2025-10-25 03:02:53 +03:00

425 lines
26 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

[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.2Template parameters[temp.param]")*s* is:
[template-parameter:](#nt:template-parameter "13.2Template parameters[temp.param]")
[*type-parameter*](#nt:type-parameter "13.2Template parameters[temp.param]")
[*parameter-declaration*](dcl.fct#nt:parameter-declaration "9.3.4.6Functions[dcl.fct]")
[*type-tt-parameter*](#nt:type-tt-parameter "13.2Template parameters[temp.param]")
[*variable-tt-parameter*](#nt:variable-tt-parameter "13.2Template parameters[temp.param]")
[*concept-tt-parameter*](#nt:concept-tt-parameter "13.2Template parameters[temp.param]")
[type-parameter:](#nt:type-parameter "13.2Template parameters[temp.param]")
[*type-parameter-key*](#nt:type-parameter-key "13.2Template parameters[temp.param]") ...opt [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]")opt
[*type-parameter-key*](#nt:type-parameter-key "13.2Template parameters[temp.param]") [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]")opt = [*type-id*](dcl.name#nt:type-id "9.3.2Type names[dcl.name]")
[*type-constraint*](#nt:type-constraint "13.2Template parameters[temp.param]") ...opt [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]")opt
[*type-constraint*](#nt:type-constraint "13.2Template parameters[temp.param]") [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]")opt = [*type-id*](dcl.name#nt:type-id "9.3.2Type names[dcl.name]")
[type-parameter-key:](#nt:type-parameter-key "13.2Template parameters[temp.param]")
class
typename
[type-constraint:](#nt:type-constraint "13.2Template parameters[temp.param]")
[*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]")opt [*concept-name*](temp.concept#nt:concept-name "13.7.9Concept definitions[temp.concept]")
[*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]")opt [*concept-name*](temp.concept#nt:concept-name "13.7.9Concept definitions[temp.concept]") < [*template-argument-list*](temp.names#nt:template-argument-list "13.3Names of template specializations[temp.names]")opt >
[type-tt-parameter:](#nt:type-tt-parameter "13.2Template parameters[temp.param]")
[*template-head*](temp.pre#nt:template-head "13.1Preamble[temp.pre]") [*type-parameter-key*](#nt:type-parameter-key "13.2Template parameters[temp.param]") ...opt [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]")opt
[*template-head*](temp.pre#nt:template-head "13.1Preamble[temp.pre]") [*type-parameter-key*](#nt:type-parameter-key "13.2Template parameters[temp.param]") [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]")opt [*type-tt-parameter-default*](#nt:type-tt-parameter-default "13.2Template parameters[temp.param]")
[type-tt-parameter-default:](#nt:type-tt-parameter-default "13.2Template parameters[temp.param]")
= [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]")opt [*template-name*](temp.names#nt:template-name "13.3Names of template specializations[temp.names]")
= [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]") template [*template-name*](temp.names#nt:template-name "13.3Names of template specializations[temp.names]")
[variable-tt-parameter:](#nt:variable-tt-parameter "13.2Template parameters[temp.param]")
[*template-head*](temp.pre#nt:template-head "13.1Preamble[temp.pre]") auto ...opt [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]")opt
[*template-head*](temp.pre#nt:template-head "13.1Preamble[temp.pre]") auto [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]")opt = [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]")opt [*template-name*](temp.names#nt:template-name "13.3Names of template specializations[temp.names]")
[concept-tt-parameter:](#nt:concept-tt-parameter "13.2Template parameters[temp.param]")
template < [*template-parameter-list*](temp.pre#nt:template-parameter-list "13.1Preamble[temp.pre]") > concept ...opt [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]")opt
template < [*template-parameter-list*](temp.pre#nt:template-parameter-list "13.1Preamble[temp.pre]") > concept [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]")opt = [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]")opt [*template-name*](temp.names#nt:template-name "13.3Names of template specializations[temp.names]")
The component names of a [*type-constraint*](#nt:type-constraint "13.2Template parameters[temp.param]") are
its [*concept-name*](temp.concept#nt:concept-name "13.7.9Concept definitions[temp.concept]") and
those of its [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified 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.1Preamble[temp.pre]") of a[*type-tt-parameter*](#nt:type-tt-parameter "13.2Template parameters[temp.param]"),[*variable-tt-parameter*](#nt:variable-tt-parameter "13.2Template parameters[temp.param]"), or[*concept-tt-parameter*](#nt:concept-tt-parameter "13.2Template parameters[temp.param]") can be the product of replacing a>> token by two consecutive > tokens ([[temp.names]](temp.names "13.3Names 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.2Template parameters[temp.param]") is
a template parameter introduced by a [*type-parameter*](#nt:type-parameter "13.2Template parameters[temp.param]")[.](#2.1.sentence-1)
- [(2.2)](#2.2)
A [*constant template parameter*](#def:template_parameter,constant "13.2Template parameters[temp.param]") is
a template parameter introduced by a [*parameter-declaration*](dcl.fct#nt:parameter-declaration "9.3.4.6Functions[dcl.fct]")[.](#2.2.sentence-1)
- [(2.3)](#2.3)
A [*type template template parameter*](#def:template_parameter,type_template "13.2Template parameters[temp.param]") is
a template parameter introduced by a [*type-tt-parameter*](#nt:type-tt-parameter "13.2Template parameters[temp.param]")[.](#2.3.sentence-1)
- [(2.4)](#2.4)
A [*variable template template parameter*](#def:template_parameter,variable_template "13.2Template parameters[temp.param]") is
a template parameter introduced by a [*variable-tt-parameter*](#nt:variable-tt-parameter "13.2Template parameters[temp.param]")[.](#2.4.sentence-1)
- [(2.5)](#2.5)
A [*concept template parameter*](#def:template_parameter,concept "13.2Template parameters[temp.param]") is
a template parameter introduced by a [*concept-tt-parameter*](#nt:concept-tt-parameter "13.2Template 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.2Template 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.3Qualified names[expr.prim.id.qual]") of a [*type-constraint*](#nt:type-constraint "13.2Template 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.3Constrained 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.2Template parameters[temp.param]") is
a [*parameter-declaration*](dcl.fct#nt:parameter-declaration "9.3.4.6Functions[dcl.fct]") that declares a pack ([[dcl.fct]](dcl.fct "9.3.4.6Functions")), or
otherwise has an ellipsis prior to its optional [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]"),
then the [*template-parameter*](#nt:template-parameter "13.2Template parameters[temp.param]") declares a template parameter pack ([[temp.variadic]](temp.variadic "13.7.4Variadic templates"))[.](#6.sentence-1)
A template parameter pack that is a [*parameter-declaration*](dcl.fct#nt:parameter-declaration "9.3.4.6Functions[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.1Preamble[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.2Template 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.1Preamble[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.2Template parameters[temp.param]")[.](#7.sentence-1)
typename followed by an[*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2Unqualified 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.3Qualified names[expr.prim.id.qual]") denotes the type in a[*parameter-declaration*](dcl.fct#nt:parameter-declaration "9.3.4.6Functions[dcl.fct]")[.](#7.sentence-3)
A [*template-parameter*](#nt:template-parameter "13.2Template parameters[temp.param]") of the formclass [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]") is a [*type-parameter*](#nt:type-parameter "13.2Template 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.6Functions[dcl.fct]") of a [*template-parameter*](#nt:template-parameter "13.2Template parameters[temp.param]") shall not have a [*storage-class-specifier*](dcl.stc#nt:storage-class-specifier "9.2.2Storage 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.11Identifiers[lex.name]") in
a [*template-parameter*](#nt:template-parameter "13.2Template parameters[temp.param]") denoting a type or template
is not looked up[.](#8.sentence-1)
An [*identifier*](lex.name#nt:identifier "5.11Identifiers[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.4The typedef specifier[dcl.typedef]") for a [*type-parameter*](#nt:type-parameter "13.2Template parameters[temp.param]"),
- [(8.2)](#8.2)
a [*template-name*](temp.names#nt:template-name "13.3Names of template specializations[temp.names]") for a [*variable-tt-parameter*](#nt:variable-tt-parameter "13.2Template parameters[temp.param]"),
- [(8.3)](#8.3)
a [*template-name*](temp.names#nt:template-name "13.3Names of template specializations[temp.names]") for a [*type-tt-parameter*](#nt:type-tt-parameter "13.2Template parameters[temp.param]"), or
- [(8.4)](#8.4)
a [*concept-name*](temp.concept#nt:concept-name "13.7.9Concept definitions[temp.concept]") for a [*concept-tt-parameter*](#nt:concept-tt-parameter "13.2Template 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.2Template 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.3Constrained 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.3Constrained declarations[temp.constr.decl]") E is called the[*immediately-declared constraint*](#def:constraint,immediately-declared "13.2Template parameters[temp.param]") of Q for T[.](#9.sentence-5)
The concept designated by a [*type-constraint*](#nt:type-constraint "13.2Template parameters[temp.param]") shall be a type concept ([[temp.concept]](temp.concept "13.7.9Concept definitions"))[.](#9.sentence-6)
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L449)
A [*type-parameter*](#nt:type-parameter "13.2Template parameters[temp.param]") that starts with a [*type-constraint*](#nt:type-constraint "13.2Template parameters[temp.param]") introduces the immediately-declared constraint
of the [*type-constraint*](#nt:type-constraint "13.2Template 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.7Placeholder 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.8Deduced class template specialization types"))[.](#11.sentence-1)
The top-level[*cv-qualifier*](dcl.decl.general#nt:cv-qualifier "9.3.1General[dcl.decl.general]")*s* on the[*template-parameter*](#nt:template-parameter "13.2Template 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.2Template 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.1General[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.2Template parameters[temp.param]"),
which is template-argument-equivalent ([[temp.type]](temp.type "13.6Type 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.3Constant 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.1General[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.2Unqualified 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.2Template parameters[temp.param]") introduces the immediately-declared constraint
of the [*type-constraint*](#nt:type-constraint "13.2Template parameters[temp.param]") for the invented type corresponding to the placeholder ([[dcl.fct]](dcl.fct "9.3.4.6Functions"))[.](#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.2Template parameters[temp.param]") is
a template argument ([[temp.arg]](temp.arg "13.4Template arguments")) specified after = in a [*template-parameter*](#nt:template-parameter "13.2Template 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.4Variadic 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.1Preamble[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.7Default 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.2Template 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.2Template 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.2Template 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.2Template parameters[temp.param]")[.](#19.sentence-2)
If a [*template-parameter*](#nt:template-parameter "13.2Template 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.2Template parameters[temp.param]") unless that template parameter is deducible from the
parameter-type-list ([[dcl.fct]](dcl.fct "9.3.4.6Functions")) of the function template or
has a default argument ([[temp.deduct]](temp.deduct "13.10.3Template argument deduction"))[.](#19.sentence-3)
A template parameter of a deduction guide template ([[temp.deduct.guide]](temp.deduct.guide "13.7.2.3Deduction 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.1Preamble[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.2Template parameters[temp.param]") of
a template [*template-parameter*](#nt:template-parameter "13.2Template 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.2Template parameters[temp.param]") in the scope of the template [*template-parameter*](#nt:template-parameter "13.2Template 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.4Concept-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*]