[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 // Types is a template type parameter packclass Tuple; // but not a pack expansiontemplate // Dims is a constant template parameter packstruct multi_array; // but not a pack expansiontemplate struct value_holder {template struct apply { }; // Values is a constant template parameter pack}; // and a pack expansiontemplate // 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 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, then let E′ be C[.](#9.sentence-2) Otherwise, let E′ be C[.](#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 concept C1 = true;template concept C2 = true;template concept C3 = true; template struct s1; // associates C1template struct s2; // associates (C1 && ...)template struct s3; // associates (C2 && ...)template T> struct s4; // associates C3template... T> struct s5; // associates (C3 && ...) — *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 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 class X; // errortemplate 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 struct R { /* ... */ };template struct S { /* ... */ };int p; R<&p> w; // OK S<&p> x; // OK due to parameter adjustmentint v[5]; R y; // OK due to implicit argument conversion S 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 A;template class A; is equivalent totemplate 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 B; // error// U can be neither deduced from the parameter-type-list nor specifiedtemplate void f() { } // errortemplate 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 4 > // syntax errorclass X { /* ... */ }; template 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