This commit is contained in:
2025-10-25 03:02:53 +03:00
commit 043225d523
3416 changed files with 681196 additions and 0 deletions

258
cppdraft/temp/names.md Normal file
View File

@@ -0,0 +1,258 @@
[temp.names]
# 13 Templates [[temp]](./#temp)
## 13.3 Names of template specializations [temp.names]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L688)
A [template specialization](temp.spec "13.9Template instantiation and specialization[temp.spec]") can be referred to by a[*template-id*](#nt:template-id "13.3Names of template specializations[temp.names]"):
[simple-template-id:](#nt:simple-template-id "13.3Names of template specializations[temp.names]")
[*template-name*](#nt:template-name "13.3Names of template specializations[temp.names]") < [*template-argument-list*](#nt:template-argument-list "13.3Names of template specializations[temp.names]")opt >
[template-id:](#nt:template-id "13.3Names of template specializations[temp.names]")
[*simple-template-id*](#nt:simple-template-id "13.3Names of template specializations[temp.names]")
[*operator-function-id*](over.oper.general#nt:operator-function-id "12.4.1General[over.oper.general]") < [*template-argument-list*](#nt:template-argument-list "13.3Names of template specializations[temp.names]")opt >
[*literal-operator-id*](over.literal#nt:literal-operator-id "12.6User-defined literals[over.literal]") < [*template-argument-list*](#nt:template-argument-list "13.3Names of template specializations[temp.names]")opt >
[template-name:](#nt:template-name "13.3Names of template specializations[temp.names]")
[*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]")
[template-argument-list:](#nt:template-argument-list "13.3Names of template specializations[temp.names]")
[*template-argument*](#nt:template-argument "13.3Names of template specializations[temp.names]") ...opt
[*template-argument-list*](#nt:template-argument-list "13.3Names of template specializations[temp.names]") , [*template-argument*](#nt:template-argument "13.3Names of template specializations[temp.names]") ...opt
[template-argument:](#nt:template-argument "13.3Names of template specializations[temp.names]")
[*constant-expression*](expr.const#nt:constant-expression "7.7Constant expressions[expr.const]")
[*type-id*](dcl.name#nt:type-id "9.3.2Type names[dcl.name]")
[*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]")opt [*template-name*](#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*](#nt:template-name "13.3Names of template specializations[temp.names]")
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L723)
The component name of a[*simple-template-id*](#nt:simple-template-id "13.3Names of template specializations[temp.names]"),[*template-id*](#nt:template-id "13.3Names of template specializations[temp.names]"), or[*template-name*](#nt:template-name "13.3Names of template specializations[temp.names]") is the first name in it[.](#2.sentence-1)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L731)
A < is interpreted as the delimiter of
a [*template-argument-list*](#nt:template-argument-list "13.3Names of template specializations[temp.names]") if either
- [(3.1)](#3.1)
it follows a [*splice-specifier*](basic.splice#nt:splice-specifier "6.6Splice specifiers[basic.splice]") that either
* [(3.1.1)](#3.1.1)
appears in a type-only context or
* [(3.1.2)](#3.1.2)
is preceded by template or typename, or
- [(3.2)](#3.2)
it follows a name that is not a [*conversion-function-id*](class.conv.fct#nt:conversion-function-id "11.4.8.3Conversion functions[class.conv.fct]") and
* [(3.2.1)](#3.2.1)
that follows the keyword template or a ~ after a [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]") or
in a class member access expression, or
* [(3.2.2)](#3.2.2)
for which name lookup finds the injected-class-name of a class template or
finds any declaration of a template, or
* [(3.2.3)](#3.2.3)
that is an unqualified name
for which name lookup either finds one or more functions or finds nothing, or
* [(3.2.4)](#3.2.4)
that is a terminal name
in a [*using-declarator*](namespace.udecl#nt:using-declarator "9.10The using declaration[namespace.udecl]") ([[namespace.udecl]](namespace.udecl "9.10The using declaration")),
in a [*declarator-id*](dcl.decl.general#nt:declarator-id "9.3.1General[dcl.decl.general]") ([[dcl.meaning]](dcl.meaning "9.3.4Meaning of declarators")), or
in a type-only context
other than a [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]") ([[temp.res]](temp.res "13.8Name resolution"))[.](#3.sentence-1)
[*Note [1](#note-1)*:
If the name is an [*identifier*](lex.name#nt:identifier "5.11Identifiers[lex.name]"),
it is then interpreted as a [*template-name*](#nt:template-name "13.3Names of template specializations[temp.names]")[.](#3.sentence-2)
The keyword template is used to indicate
that a dependent qualified name ([[temp.dep.type]](temp.dep.type "13.8.3.2Dependent types")) denotes a template
where an expression might appear[.](#3.sentence-3)
— *end note*]
[*Example [1](#example-1)*: struct X {template<std::size_t> X* alloc(); template<std::size_t> static X* adjust();};template<class T> void f(T* p) { T* p1 = p->alloc<200>(); // error: < means less than T* p2 = p->template alloc<200>(); // OK, < starts template argument list T::adjust<100>(); // error: < means less than T::template adjust<100>(); // OK, < starts template argument liststatic constexpr std::meta::info r = ^^T::adjust;
T* p3 = [:r:]<200>(); // error: < means less than T* p4 = template [:r:]<200>(); // OK, < starts template argument list}} — *end example*]
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L789)
When parsing a [*template-argument-list*](#nt:template-argument-list "13.3Names of template specializations[temp.names]"),
the first non-nested>[108](#footnote-108 "A > that encloses the type-id of a dynamic_­cast, static_­cast, reinterpret_­cast or const_­cast, or which encloses the template-arguments of a subsequent template-id or splice-specialization-specifier, is considered nested for the purpose of this description.") is taken as the ending delimiter
rather than a greater-than operator[.](#4.sentence-1)
Similarly, the first non-nested >> is treated as two
consecutive but distinct > tokens, the first of which is taken
as the end of the [*template-argument-list*](#nt:template-argument-list "13.3Names of template specializations[temp.names]") and completes
the [*template-id*](#nt:template-id "13.3Names of template specializations[temp.names]") or [*splice-specialization-specifier*](basic.splice#nt:splice-specialization-specifier "6.6Splice specifiers[basic.splice]")[.](#4.sentence-2)
[*Note [2](#note-2)*:
The second > token produced by this replacement rule can terminate an enclosing[*template-id*](#nt:template-id "13.3Names of template specializations[temp.names]") or [*splice-specialization-specifier*](basic.splice#nt:splice-specialization-specifier "6.6Splice specifiers[basic.splice]") construct or it can be part of a different construct (e.g., a cast)[.](#4.sentence-3)
— *end note*]
[*Example [2](#example-2)*: template<int i> class X { /* ... */ };
X< 1>2 > x1; // syntax error X<(1>2)> x2; // OKtemplate<class T> class Y { /* ... */ };
Y<X<1>> x3; // OK, same as Y<X<1> > x3; Y<X<6>>1>> x4; // syntax error Y<X<(6>>1)>> x5; // OK — *end example*]
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L828)
The keyword template shall not appear immediately after
a declarative [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3Qualified names[expr.prim.id.qual]") ([[expr.prim.id.qual]](expr.prim.id.qual "7.5.5.3Qualified names"))[.](#5.sentence-1)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L832)
The [*constant-expression*](expr.const#nt:constant-expression "7.7Constant expressions[expr.const]") of a [*template-argument*](#nt:template-argument "13.3Names of template specializations[temp.names]") shall not be an unparenthesized [*splice-expression*](expr.prim.splice#nt:splice-expression "7.5.9Expression splicing[expr.prim.splice]")[.](#6.sentence-1)
[*Example [3](#example-3)*: template<int> struct S { };constexpr int k = 5;constexpr std::meta::info r = ^^k;
S<[:r:]> s1; // error: unparenthesized [*splice-expression*](expr.prim.splice#nt:splice-expression "7.5.9Expression splicing[expr.prim.splice]") used as template argument S<([:r:])> s2; // OK S<[:r:] + 1> s3; // OK — *end example*]
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L846)
A name prefixed by the keywordtemplate shall be followed by a template argument list or
refer to a class template or an alias template[.](#7.sentence-1)
The latter case is deprecated ([[depr.template.template]](depr.template.template "D.9template keyword before qualified names"))[.](#7.sentence-2)
The keyword template shall not appear immediately
before a ~ token (as to name a destructor)[.](#7.sentence-3)
[*Note [3](#note-3)*:
The keywordtemplate cannot be applied to non-template members of class templates[.](#7.sentence-4)
— *end note*]
[*Note [4](#note-4)*:
As is the case with thetypename prefix, thetemplate prefix is well-formed
even when lookup for the name would already find a template[.](#7.sentence-5)
— *end note*]
[*Example [4](#example-4)*: template <class T> struct A {void f(int); template <class U> void f(U);};
template <class T> void f(T t) { A<T> a;
a.template f<>(t); // OK, calls template a.template f(t); // error: not a [*template-id*](#nt:template-id "13.3Names of template specializations[temp.names]")}template <class T> struct B {template <class T2> struct C { };};
// deprecated: T::C is assumed to name a class template:template <class T, template <class X> class TT = T::template C> struct D { };
D<B<int> > db; — *end example*]
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L890)
A [*template-id*](#nt:template-id "13.3Names of template specializations[temp.names]") or [*splice-specialization-specifier*](basic.splice#nt:splice-specialization-specifier "6.6Splice specifiers[basic.splice]") is [*valid*](#def:template-id,valid "13.3Names of template specializations[temp.names]") if
- [(8.1)](#8.1)
there are at most as many arguments as there are parameters
or a parameter is a template parameter pack ([[temp.variadic]](temp.variadic "13.7.4Variadic templates")),
- [(8.2)](#8.2)
there is an argument for each non-deducible non-pack parameter
that does not have a default [*template-argument*](#nt:template-argument "13.3Names of template specializations[temp.names]"),
- [(8.3)](#8.3)
each [*template-argument*](#nt:template-argument "13.3Names of template specializations[temp.names]") matches the corresponding
template parameter ([[temp.arg]](temp.arg "13.4Template arguments")),
- [(8.4)](#8.4)
substitution of each template argument into the following
template parameters (if any) succeeds, and
- [(8.5)](#8.5)
if the [*template-id*](#nt:template-id "13.3Names of template specializations[temp.names]") or [*splice-specialization-specifier*](basic.splice#nt:splice-specialization-specifier "6.6Splice specifiers[basic.splice]") is non-dependent,
the associated constraints are satisfied as specified in the next paragraph[.](#8.sentence-1)
A [*simple-template-id*](#nt:simple-template-id "13.3Names of template specializations[temp.names]") or[*splice-specialization-specifier*](basic.splice#nt:splice-specialization-specifier "6.6Splice specifiers[basic.splice]") shall be valid unless its respective[*template-name*](#nt:template-name "13.3Names of template specializations[temp.names]") or [*splice-specifier*](basic.splice#nt:splice-specifier "6.6Splice specifiers[basic.splice]") names or designates a function template ([[temp.deduct]](temp.deduct "13.10.3Template argument deduction"))[.](#8.sentence-2)
[*Example [5](#example-5)*: template<class T, T::type n = 0> class X;struct S {using type = int;};using T1 = X<S, int, int>; // error: too many argumentsusing T2 = X<>; // error: no default argument for first template parameterusing T3 = X<1>; // error: value 1 does not match type-parameterusing T4 = X<int>; // error: substitution failure for second template parameterusing T5 = X<S>; // OK — *end example*]
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L934)
When the [*template-name*](#nt:template-name "13.3Names of template specializations[temp.names]") of a [*simple-template-id*](#nt:simple-template-id "13.3Names of template specializations[temp.names]") or
the [*splice-specifier*](basic.splice#nt:splice-specifier "6.6Splice specifiers[basic.splice]") of a [*splice-specialization-specifier*](basic.splice#nt:splice-specialization-specifier "6.6Splice specifiers[basic.splice]") designates a constrained non-function template
or
a constrained template template parameter,
and
all [*template-argument*](#nt:template-argument "13.3Names of template specializations[temp.names]")*s* in the [*simple-template-id*](#nt:simple-template-id "13.3Names of template specializations[temp.names]") or[*splice-specialization-specifier*](basic.splice#nt:splice-specialization-specifier "6.6Splice specifiers[basic.splice]") are non-dependent ([[temp.dep.temp]](temp.dep.temp "13.8.3.7Dependent template arguments")),
the associated constraints ([[temp.constr.decl]](temp.constr.decl "13.5.3Constrained declarations"))
of the constrained template
shall be satisfied ([[temp.constr.constr]](temp.constr.constr "13.5.2Constraints"))[.](#9.sentence-1)
[*Example [6](#example-6)*: template<typename T> concept C1 = sizeof(T) != sizeof(int);
template<C1 T> struct S1 { };template<C1 T> using Ptr = T*;
S1<int>* p; // error: constraints not satisfied Ptr<int> p; // error: constraints not satisfiedtemplate<typename T>struct S2 { Ptr<int> x; }; // ill-formed, no diagnostic requiredtemplate<typename T>struct S3 { Ptr<T> x; }; // OK, satisfaction is not required S3<int> x; // error: constraints not satisfiedtemplate<template<C1 T> class X>struct S4 { X<int> x; // ill-formed, no diagnostic required};
template<typename T> concept C2 = sizeof(T) == 1;
template<C2 T> struct S { };
template struct S<char[2]>; // error: constraints not satisfiedtemplate<> struct S<char[2]> { }; // error: constraints not satisfied — *end example*]
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L982)
A [*concept-id*](#def:concept-id "13.3Names of template specializations[temp.names]") is a [*simple-template-id*](#nt:simple-template-id "13.3Names of template specializations[temp.names]") where the [*template-name*](#nt:template-name "13.3Names of template specializations[temp.names]") is a [*concept-name*](temp.concept#nt:concept-name "13.7.9Concept definitions[temp.concept]")[.](#10.sentence-1)
A concept-id is a prvalue of type bool, and
does not name a template specialization[.](#10.sentence-2)
A concept-id evaluates to true if the concept's
normalized [*constraint-expression*](temp.constr.decl#nt:constraint-expression "13.5.3Constrained declarations[temp.constr.decl]") ([[temp.constr.decl]](temp.constr.decl "13.5.3Constrained declarations"))
is satisfied ([[temp.constr.constr]](temp.constr.constr "13.5.2Constraints")) by the specified template arguments andfalse otherwise[.](#10.sentence-3)
[*Note [5](#note-5)*:
Since a [*constraint-expression*](temp.constr.decl#nt:constraint-expression "13.5.3Constrained declarations[temp.constr.decl]") is an unevaluated operand,
a concept-id appearing in a [*constraint-expression*](temp.constr.decl#nt:constraint-expression "13.5.3Constrained declarations[temp.constr.decl]") is not evaluated except as necessary
to determine whether the normalized constraints are satisfied[.](#10.sentence-4)
— *end note*]
[*Example [7](#example-7)*: template<typename T> concept C = true;static_assert(C<int>); // OK — *end example*]
[108)](#footnote-108)[108)](#footnoteref-108)
A > that encloses the [*type-id*](dcl.name#nt:type-id "9.3.2Type names[dcl.name]") of a dynamic_cast, static_cast, reinterpret_cast or const_cast, or which encloses the [*template-argument*](#nt:template-argument "13.3Names of template specializations[temp.names]")*s* of a subsequent [*template-id*](#nt:template-id "13.3Names of template specializations[temp.names]") or[*splice-specialization-specifier*](basic.splice#nt:splice-specialization-specifier "6.6Splice specifiers[basic.splice]"),
is considered nested for the purpose of this description[.](#footnote-108.sentence-1)