425 lines
26 KiB
Markdown
425 lines
26 KiB
Markdown
[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*]
|