Files
2025-10-25 03:02:53 +03:00

242 lines
13 KiB
Markdown
Raw Permalink 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.pre]
# 13 Templates [[temp]](./#temp)
## 13.1 Preamble [temp.pre]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L12)
A [*template*](#def:template "13.1Preamble[temp.pre]") defines a family of classes, functions, or variables,
an alias for a family of types, or a concept[.](#1.sentence-1)
[template-declaration:](#nt:template-declaration "13.1Preamble[temp.pre]")
[*template-head*](#nt:template-head "13.1Preamble[temp.pre]") [*declaration*](dcl.pre#nt:declaration "9.1Preamble[dcl.pre]")
[*template-head*](#nt:template-head "13.1Preamble[temp.pre]") [*concept-definition*](temp.concept#nt:concept-definition "13.7.9Concept definitions[temp.concept]")
[template-head:](#nt:template-head "13.1Preamble[temp.pre]")
template < [*template-parameter-list*](#nt:template-parameter-list "13.1Preamble[temp.pre]") > [*requires-clause*](#nt:requires-clause "13.1Preamble[temp.pre]")opt
[template-parameter-list:](#nt:template-parameter-list "13.1Preamble[temp.pre]")
[*template-parameter*](temp.param#nt:template-parameter "13.2Template parameters[temp.param]")
[*template-parameter-list*](#nt:template-parameter-list "13.1Preamble[temp.pre]") , [*template-parameter*](temp.param#nt:template-parameter "13.2Template parameters[temp.param]")
[requires-clause:](#nt:requires-clause "13.1Preamble[temp.pre]")
requires [*constraint-logical-or-expression*](#nt:constraint-logical-or-expression "13.1Preamble[temp.pre]")
[constraint-logical-or-expression:](#nt:constraint-logical-or-expression "13.1Preamble[temp.pre]")
[*constraint-logical-and-expression*](#nt:constraint-logical-and-expression "13.1Preamble[temp.pre]")
[*constraint-logical-or-expression*](#nt:constraint-logical-or-expression "13.1Preamble[temp.pre]") || [*constraint-logical-and-expression*](#nt:constraint-logical-and-expression "13.1Preamble[temp.pre]")
[constraint-logical-and-expression:](#nt:constraint-logical-and-expression "13.1Preamble[temp.pre]")
[*primary-expression*](expr.prim.grammar#nt:primary-expression "7.5.1Grammar[expr.prim.grammar]")
[*constraint-logical-and-expression*](#nt:constraint-logical-and-expression "13.1Preamble[temp.pre]") && [*primary-expression*](expr.prim.grammar#nt:primary-expression "7.5.1Grammar[expr.prim.grammar]")
[*Note [1](#note-1)*:
The > token following the[*template-parameter-list*](#nt:template-parameter-list "13.1Preamble[temp.pre]") of a[*template-declaration*](#nt:template-declaration "13.1Preamble[temp.pre]") can be the product of replacing a>> token by two consecutive > tokens ([[temp.names]](temp.names "13.3Names of template specializations"))[.](#1.sentence-2)
— *end note*]
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L61)
The [*declaration*](dcl.pre#nt:declaration "9.1Preamble[dcl.pre]") in a [*template-declaration*](#nt:template-declaration "13.1Preamble[temp.pre]") (if any)
shall
- [(2.1)](#2.1)
declare or define a function, a class, or a variable, or
- [(2.2)](#2.2)
define a member function, a member class, a member enumeration, or a static data member of a
class template or of a class nested within a class template, or
- [(2.3)](#2.3)
define a member template of a class or class template, or
- [(2.4)](#2.4)
be a [*friend-type-declaration*](class.mem.general#nt:friend-type-declaration "11.4.1General[class.mem.general]"), or
- [(2.5)](#2.5)
be a [*deduction-guide*](temp.deduct.guide#nt:deduction-guide "13.7.2.3Deduction guides[temp.deduct.guide]"), or
- [(2.6)](#2.6)
be an [*alias-declaration*](dcl.pre#nt:alias-declaration "9.1Preamble[dcl.pre]")[.](#2.sentence-1)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L79)
A [*template-declaration*](#nt:template-declaration "13.1Preamble[temp.pre]") is a [*declaration*](dcl.pre#nt:declaration "9.1Preamble[dcl.pre]")[.](#3.sentence-1)
A declaration introduced by a template declaration of avariable is a [*variable template*](#def:template,variable "13.1Preamble[temp.pre]")[.](#3.sentence-2)
A variable template at class scope is a[*static data member template*](#def:template,static_data_member "13.1Preamble[temp.pre]")[.](#3.sentence-3)
[*Example [1](#example-1)*: template<class T>constexpr T pi = T(3.1415926535897932385L);template<class T> T circular_area(T r) {return pi<T> * r * r; }struct matrix_constants {template<class T>using pauli = hermitian_matrix<T, 2>; template<class T>constexpr static pauli<T> sigma1 = { { 0, 1 }, { 1, 0 } }; template<class T>constexpr static pauli<T> sigma2 = { { 0, -1i }, { 1i, 0 } }; template<class T>constexpr static pauli<T> sigma3 = { { 1, 0 }, { 0, -1 } };}; — *end example*]
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L107)
[*Note [2](#note-2)*:
A [*template-declaration*](#nt:template-declaration "13.1Preamble[temp.pre]") can appear only as a namespace scope or class scope declaration[.](#4.sentence-1)
— *end note*]
Its [*declaration*](dcl.pre#nt:declaration "9.1Preamble[dcl.pre]") shall not be an[*export-declaration*](module.interface#nt:export-declaration "10.2Export declaration[module.interface]")[.](#4.sentence-2)
In a function template declaration, the [*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2Unqualified names[expr.prim.id.unqual]") of the[*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1General[dcl.decl.general]") shall be a name[.](#4.sentence-3)
[*Note [3](#note-3)*:
A class or variable template declaration of a [*simple-template-id*](temp.names#nt:simple-template-id "13.3Names of template specializations[temp.names]") declares a partial specialization ([[temp.spec.partial]](temp.spec.partial "13.7.6Partial specialization"))[.](#4.sentence-4)
— *end note*]
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L121)
In a[*template-declaration*](#nt:template-declaration "13.1Preamble[temp.pre]"),
explicit specialization, or explicit instantiation, the[*init-declarator-list*](dcl.decl.general#nt:init-declarator-list "9.3.1General[dcl.decl.general]") in the declaration shall contain at most one declarator[.](#5.sentence-1)
When such a declaration is used to declare a class template,
no declarator is permitted[.](#5.sentence-2)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L130)
A specialization (explicit or implicit) of one template is
distinct from all specializations of any other template[.](#6.sentence-1)
A template, an explicit specialization ([[temp.expl.spec]](temp.expl.spec "13.9.4Explicit specialization")), and a
partial specialization shall not have C language linkage[.](#6.sentence-2)
[*Note [4](#note-4)*:
Default arguments for function templates and for member functions of
class templates are considered definitions for the purpose of template
instantiation ([[temp.decls]](temp.decls "13.7Template declarations")) and must obey the one-definition rule ([[basic.def.odr]](basic.def.odr "6.3One-definition rule"))[.](#6.sentence-3)
— *end note*]
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L142)
[*Note [5](#note-5)*:
A template cannot have the same name as any other
name bound in the same scope ([[basic.scope.scope]](basic.scope.scope "6.4.1General")), except
that a function template can share a name with [*using-declarator*](namespace.udecl#nt:using-declarator "9.10The using declaration[namespace.udecl]")*s*,
a type, non-template functions ([[dcl.fct]](dcl.fct "9.3.4.6Functions")) and/or function templates ([[temp.over]](temp.over "13.10.4Overload resolution"))[.](#7.sentence-1)
Specializations, including partial specializations ([[temp.spec.partial]](temp.spec.partial "13.7.6Partial specialization")),
do not reintroduce or bind names[.](#7.sentence-2)
Their target scope is the target scope of the primary template,
so all specializations of a template belong to the same scope as it does[.](#7.sentence-3)
[*Example [2](#example-2)*: void f() {}class f {}; // OKnamespace N {void f(int) {}}using N::f; // OKtemplate<typename> void f(long) {} // #1, OKtemplate<typename> void f(long) {} // error: redefinition of #1template<typename> void f(long long) {} // OKtemplate<> void f<int>(long long) {} // OK, doesn't bind a name — *end example*]
— *end note*]
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L168)
An entity is [*templated*](#def:templated "13.1Preamble[temp.pre]") if it is
- [(8.1)](#8.1)
a template,
- [(8.2)](#8.2)
an entity defined ([[basic.def]](basic.def "6.2Declarations and definitions")) or created ([[class.temporary]](class.temporary "6.8.7Temporary objects"))
within the [*compound-statement*](stmt.block#nt:compound-statement "8.4Compound statement or block[stmt.block]") of an expansion statement ([[stmt.expand]](stmt.expand "8.7Expansion statements")),
- [(8.3)](#8.3)
an entity defined or created in a templated entity,
- [(8.4)](#8.4)
a member of a templated entity,
- [(8.5)](#8.5)
an enumerator for an enumeration that is a templated entity, or
- [(8.6)](#8.6)
the closure type of a [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1General[expr.prim.lambda.general]") ([[expr.prim.lambda.closure]](expr.prim.lambda.closure "7.5.6.2Closure types"))
appearing in the declaration of a templated entity[.](#8.sentence-1)
[*Note [6](#note-6)*:
A local class, a local or block variable, or a friend function defined in a
templated entity is a templated entity[.](#8.sentence-2)
— *end note*]
A [*templated function*](#def:function,templated "13.1Preamble[temp.pre]") is
a function template or a function that is templated[.](#8.sentence-3)
A [*templated class*](#def:class,templated "13.1Preamble[temp.pre]") is
a class template or a class that is templated[.](#8.sentence-4)
A [*templated variable*](#def:variable,templated "13.1Preamble[temp.pre]") is
a variable template or a variable that is templated[.](#8.sentence-5)
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L196)
A [*template-declaration*](#nt:template-declaration "13.1Preamble[temp.pre]") is written
in terms of its template parameters[.](#9.sentence-1)
The optional [*requires-clause*](#nt:requires-clause "13.1Preamble[temp.pre]") following a[*template-parameter-list*](#nt:template-parameter-list "13.1Preamble[temp.pre]") allows the specification of
constraints ([[temp.constr.decl]](temp.constr.decl "13.5.3Constrained declarations")) on template arguments ([[temp.arg]](temp.arg "13.4Template arguments"))[.](#9.sentence-2)
The [*requires-clause*](#nt:requires-clause "13.1Preamble[temp.pre]") introduces the[*constraint-expression*](temp.constr.decl#nt:constraint-expression "13.5.3Constrained declarations[temp.constr.decl]") that results from interpreting
the [*constraint-logical-or-expression*](#nt:constraint-logical-or-expression "13.1Preamble[temp.pre]") as a[*constraint-expression*](temp.constr.decl#nt:constraint-expression "13.5.3Constrained declarations[temp.constr.decl]")[.](#9.sentence-3)
The [*constraint-logical-or-expression*](#nt:constraint-logical-or-expression "13.1Preamble[temp.pre]") of a[*requires-clause*](#nt:requires-clause "13.1Preamble[temp.pre]") is an unevaluated operand ([[expr.context]](expr.context "7.2.3Context dependence"))[.](#9.sentence-4)
[*Note [7](#note-7)*:
The expression in a [*requires-clause*](#nt:requires-clause "13.1Preamble[temp.pre]") uses a restricted grammar to avoid ambiguities[.](#9.sentence-5)
Parentheses can be used to specify arbitrary expressions
in a [*requires-clause*](#nt:requires-clause "13.1Preamble[temp.pre]")[.](#9.sentence-6)
[*Example [3](#example-3)*: template<int N> requires N == sizeof new unsigned shortint f(); // error: parentheses required around == expression — *end example*]
— *end note*]
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L221)
A definition of
a function template,
member function of a class template,
variable template,
or static data member of a class template
shall be reachable from the end of every definition domain ([[basic.def.odr]](basic.def.odr "6.3One-definition rule"))
in which it is implicitly instantiated ([[temp.inst]](temp.inst "13.9.2Implicit instantiation")) unless the
corresponding specialization is explicitly instantiated ([[temp.explicit]](temp.explicit "13.9.3Explicit instantiation"))
in some translation unit; no diagnostic is required[.](#10.sentence-1)