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

13 KiB

[temp.pre]

13 Templates [temp]

13.1 Preamble [temp.pre]

1

#

A template defines a family of classes, functions, or variables, an alias for a family of types, or a concept.

template-declaration:
template-head declaration
template-head concept-definition

template-head:
template < template-parameter-list > requires-clauseopt

template-parameter-list:
template-parameter
template-parameter-list , template-parameter

requires-clause:
requires constraint-logical-or-expression

constraint-logical-or-expression:
constraint-logical-and-expression
constraint-logical-or-expression || constraint-logical-and-expression

constraint-logical-and-expression:
primary-expression
constraint-logical-and-expression && primary-expression

[Note 1:

The > token following thetemplate-parameter-list of atemplate-declaration can be the product of replacing a>> token by two consecutive > tokens ([temp.names]).

— end note]

2

#

The declaration in a template-declaration (if any) shall

declare or define a function, a class, or a variable, or

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

define a member template of a class or class template, or

be a friend-type-declaration, or

be a deduction-guide, or

be an alias-declaration.

3

#

A template-declaration is a declaration.

A declaration introduced by a template declaration of avariable is a variable template.

A variable template at class scope is astatic data member template.

[Example 1: templateconstexpr T pi = T(3.1415926535897932385L);template T circular_area(T r) {return pi * r * r; }struct matrix_constants {templateusing pauli = hermitian_matrix<T, 2>; templateconstexpr static pauli sigma1 = { { 0, 1 }, { 1, 0 } }; templateconstexpr static pauli sigma2 = { { 0, -1i }, { 1i, 0 } }; templateconstexpr static pauli sigma3 = { { 1, 0 }, { 0, -1 } };}; — end example]

4

#

[Note 2:

A template-declaration can appear only as a namespace scope or class scope declaration.

— end note]

Its declaration shall not be anexport-declaration.

In a function template declaration, the unqualified-id of thedeclarator-id shall be a name.

[Note 3:

A class or variable template declaration of a simple-template-id declares a partial specialization ([temp.spec.partial]).

— end note]

5

#

In atemplate-declaration, explicit specialization, or explicit instantiation, theinit-declarator-list in the declaration shall contain at most one declarator.

When such a declaration is used to declare a class template, no declarator is permitted.

6

#

A specialization (explicit or implicit) of one template is distinct from all specializations of any other template.

A template, an explicit specialization ([temp.expl.spec]), and a partial specialization shall not have C language linkage.

[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]) and must obey the one-definition rule ([basic.def.odr]).

— end note]

7

#

[Note 5:

A template cannot have the same name as any other name bound in the same scope ([basic.scope.scope]), except that a function template can share a name with using-declarators, a type, non-template functions ([dcl.fct]) and/or function templates ([temp.over]).

Specializations, including partial specializations ([temp.spec.partial]), do not reintroduce or bind names.

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.

[Example 2: void f() {}class f {}; // OKnamespace N {void f(int) {}}using N::f; // OKtemplate void f(long) {} // #1, OKtemplate void f(long) {} // error: redefinition of #1template void f(long long) {} // OKtemplate<> void f(long long) {} // OK, doesn't bind a name — end example]

— end note]

8

#

An entity is templated if it is

a template,

an entity defined ([basic.def]) or created ([class.temporary]) within the compound-statement of an expansion statement ([stmt.expand]),

an entity defined or created in a templated entity,

a member of a templated entity,

an enumerator for an enumeration that is a templated entity, or

the closure type of a lambda-expression ([expr.prim.lambda.closure]) appearing in the declaration of a templated entity.

[Note 6:

A local class, a local or block variable, or a friend function defined in a templated entity is a templated entity.

— end note]

A templated function is a function template or a function that is templated.

A templated class is a class template or a class that is templated.

A templated variable is a variable template or a variable that is templated.

9

#

A template-declaration is written in terms of its template parameters.

The optional requires-clause following atemplate-parameter-list allows the specification of constraints ([temp.constr.decl]) on template arguments ([temp.arg]).

The requires-clause introduces theconstraint-expression that results from interpreting the constraint-logical-or-expression as aconstraint-expression.

The constraint-logical-or-expression of arequires-clause is an unevaluated operand ([expr.context]).

[Note 7:

The expression in a requires-clause uses a restricted grammar to avoid ambiguities.

Parentheses can be used to specify arbitrary expressions in a requires-clause.

[Example 3: template requires N == sizeof new unsigned shortint f(); // error: parentheses required around == expression — end example]

— end note]

10

#

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]) in which it is implicitly instantiated ([temp.inst]) unless the corresponding specialization is explicitly instantiated ([temp.explicit]) in some translation unit; no diagnostic is required.