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

412
cppdraft/temp/inst.md Normal file
View File

@@ -0,0 +1,412 @@
[temp.inst]
# 13 Templates [[temp]](./#temp)
## 13.9 Template instantiation and specialization [[temp.spec]](temp.spec#temp.inst)
### 13.9.2 Implicit instantiation [temp.inst]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L6485)
A template specialization E is a [*declared specialization*](#def:specialization,declared "13.9.2Implicit instantiation[temp.inst]") if there is a reachable
explicit instantiation definition ([[temp.explicit]](temp.explicit "13.9.3Explicit instantiation")) or
explicit specialization declaration ([[temp.expl.spec]](temp.expl.spec "13.9.4Explicit specialization"))
for E, or
if there is a reachable explicit instantiation declaration for E andE is not
- [(1.1)](#1.1)
an inline function,
- [(1.2)](#1.2)
declared with a type deduced
from its initializer or return value ([[dcl.spec.auto]](dcl.spec.auto "9.2.9.7Placeholder type specifiers")),
- [(1.3)](#1.3)
a potentially-constant variable ([[expr.const]](expr.const "7.7Constant expressions")), or
- [(1.4)](#1.4)
a specialization of a templated class[.](#1.sentence-1)
[*Note [1](#note-1)*:
An implicit instantiation in an importing translation unit
cannot use names with internal linkage
from an imported translation unit ([[basic.link]](basic.link "6.7Program and linkage"))[.](#1.sentence-2)
— *end note*]
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L6510)
Unless a class template specialization is a declared specialization,
the class template specialization is implicitly instantiated when the
specialization is referenced in a context that requires a completely-defined
object type or when the completeness of the class type affects the semantics
of the program[.](#2.sentence-1)
[*Note [2](#note-2)*:
In particular, if the semantics of an expression depend on the member or
base class lists of a class template specialization, the class template
specialization is implicitly generated[.](#2.sentence-2)
For instance, deleting a pointer
to class type depends on whether or not the class declares a destructor,
and a conversion between pointers to class type depends on the
inheritance relationship between the two classes involved[.](#2.sentence-3)
— *end note*]
[*Example [1](#example-1)*: template<class T> class B { /* ... */ };template<class T> class D : public B<T> { /* ... */ };
void f(void*);void f(B<int>*);
void g(D<int>* p, D<char>* pp, D<double>* ppp) { f(p); // instantiation of D<int> required: call f(B<int>*) B<char>* q = pp; // instantiation of D<char> required: convert D<char>* to B<char>*delete ppp; // instantiation of D<double> required} — *end example*]
If the template selected for the specialization ([[temp.spec.partial.match]](temp.spec.partial.match "13.7.6.2Matching of partial specializations"))
has been declared, but not defined,
at the point of instantiation ([[temp.point]](temp.point "13.8.4.1Point of instantiation")),
the instantiation yields an incomplete class type ([[basic.types.general]](basic.types.general#term.incomplete.type "6.9.1General"))[.](#2.sentence-4)
[*Example [2](#example-2)*: template<class T> class X;
X<char> ch; // error: incomplete type X<char> — *end example*]
[*Note [3](#note-3)*:
Within a template declaration,
a [local class](class.local "11.6Local class declarations[class.local]") or enumeration and the members of
a local class are never considered to be entities that can be separately
instantiated (this includes their default arguments,[*noexcept-specifier*](except.spec#nt:noexcept-specifier "14.5Exception specifications[except.spec]")*s*, and non-static data member
initializers, if any,
but not their [*type-constraint*](temp.param#nt:type-constraint "13.2Template parameters[temp.param]")*s* or [*requires-clause*](temp.pre#nt:requires-clause "13.1Preamble[temp.pre]")*s*)[.](#2.sentence-5)
As a result, the dependent names are looked up, the
semantic constraints are checked, and any templates used are instantiated as
part of the instantiation of the entity within which the local class or
enumeration is declared[.](#2.sentence-6)
— *end note*]
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L6564)
The implicit instantiation of a class template specialization causes
- [(3.1)](#3.1)
the implicit instantiation of the declarations, but not of the definitions,
of the non-deleted
class member functions,
member classes,
scoped member enumerations,
static data members,
member templates, and
friends; and
- [(3.2)](#3.2)
the implicit instantiation of the definitions of
deleted member functions,
unscoped member enumerations, and
member anonymous unions[.](#3.sentence-1)
The implicit instantiation of a class template specialization
does not cause the implicit instantiation of
default arguments or [*noexcept-specifier*](except.spec#nt:noexcept-specifier "14.5Exception specifications[except.spec]")*s* of the class member functions[.](#3.sentence-2)
[*Example [3](#example-3)*: template<class T>struct C {void f() { T x; }void g() = delete;};
C<void> c; // OK, definition of C<void>::f is not instantiated at this pointtemplate<> void C<int>::g() { } // error: redefinition of C<int>::g — *end example*]
However, for the purpose of determining whether an instantiated redeclaration
is valid according to [[basic.def.odr]](basic.def.odr "6.3One-definition rule") and [[class.mem]](class.mem "11.4Class members"),
an instantiated declaration that corresponds to a definition in the template
is considered to be a definition[.](#3.sentence-3)
[*Example [4](#example-4)*: template<class T, class U>struct Outer {template<class X, class Y> struct Inner; template<class Y> struct Inner<T, Y>; // #1atemplate<class Y> struct Inner<T, Y> { }; // #1b; OK, valid redeclaration of #1atemplate<class Y> struct Inner<U, Y> { }; // #2};
Outer<int, int> outer; // error at #2
Outer<int, int>::Inner<int, Y> is redeclared at #1b[.](#3.sentence-4)
(It is not defined
but noted as being associated with a definition in Outer<T, U>[.](#3.sentence-5))
#2
is also a redeclaration of #1a[.](#3.sentence-6)
It is noted as associated with a definition,
so it is an invalid redeclaration of the same partial specialization[.](#3.sentence-7)
template<typename T> struct Friendly {template<typename U> friend int f(U) { return sizeof(T); }};
Friendly<char> fc;
Friendly<float> ff; // error: produces second definition of f(U) — *end example*]
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L6628)
Unless a member of a templated class is a declared specialization,
the specialization of the member is implicitly instantiated when the
specialization is referenced in a context that requires the member definition
to exist or
if the existence of the definition of the member
affects the semantics of the program;
in particular, the initialization (and any associated side effects) of a
static data member does not occur unless the static data member is itself used
in a way that requires the definition of the static data member to exist[.](#4.sentence-1)
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L6639)
Unless a function template specialization is a declared specialization,
the function template specialization is implicitly instantiated when the
specialization is referenced in a context that requires a function definition
to exist or
if the existence of the definition affects the semantics of the program[.](#5.sentence-1)
A function whose declaration was instantiated from a friend function definition is
implicitly instantiated when it is referenced in a context that
requires a function definition to exist or
if the existence of the definition affects the semantics of the program[.](#5.sentence-2)
Unless a call is to a function template explicit specialization or
to a member function of an explicitly specialized class template,
a default argument for a function template or a member function of a
class template is implicitly instantiated when the function is
called in a context that requires the value of the default argument[.](#5.sentence-3)
[*Note [4](#note-4)*:
An inline function
that is the subject of an explicit instantiation declaration
is not a declared specialization;
the intent is that it still be implicitly instantiated
when odr-used ([[basic.def.odr]](basic.def.odr#term.odr.use "6.3One-definition rule"))
so that the body can be considered for inlining,
but that no out-of-line copy of it be generated in the translation unit[.](#5.sentence-4)
— *end note*]
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L6664)
[*Example [5](#example-5)*: template<class T> struct Z {void f(); void g();};
void h() { Z<int> a; // instantiation of class Z<int> required Z<char>* p; // instantiation of class Z<char> not required Z<double>* q; // instantiation of class Z<double> not required a.f(); // instantiation of Z<int>::f() required p->g(); // instantiation of class Z<char> required, and// instantiation of Z<char>::g() required}
Nothing in this example requiresclassZ<double>,Z<int>::g(),
orZ<char>::f() to be implicitly instantiated[.](#6.sentence-1)
— *end example*]
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L6692)
Unless a variable template specialization is a declared specialization,
the variable template specialization is implicitly instantiated
when it is referenced in a context
that requires a variable definition to exist or
if the existence of the definition affects the semantics of the program[.](#7.sentence-1)
A default template argument for a variable template is implicitly instantiated
when the variable template is referenced in a context
that requires the value of the default argument[.](#7.sentence-2)
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L6702)
The existence of a definition of a variable or function
is considered to affect the semantics of the program
if the variable or function
is needed for constant evaluation by an expression ([[expr.const]](expr.const "7.7Constant expressions")),
even if constant evaluation of the expression is not required or
if constant expression evaluation does not use the definition[.](#8.sentence-1)
[*Example [6](#example-6)*: template<typename T> constexpr int f() { return T::value; }template<bool B, typename T> void g(decltype(B ? f<T>() : 0));template<bool B, typename T> void g(...);template<bool B, typename T> void h(decltype(int{B ? f<T>() : 0}));template<bool B, typename T> void h(...);void x() { g<false, int>(0); // OK, B ? f<T>() : 0 is not potentially constant evaluated h<false, int>(0); // error, instantiates f<int> even though B evaluates to false and// list-initialization of int from int cannot be narrowing} — *end example*]
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L6729)
If the function selected by [overload resolution](over.match "12.2Overload resolution[over.match]") can be determined without instantiating a class template definition,
it is unspecified whether that instantiation actually takes place[.](#9.sentence-1)
[*Example [7](#example-7)*: template <class T> struct S {operator int();};
void f(int);void f(S<int>&);void f(S<float>);
void g(S<int>& sr) { f(sr); // instantiation of S<int> allowed but not required// instantiation of S<float> allowed but not required}; — *end example*]
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L6750)
If a function template or a member function template specialization is used in
a way that involves overload resolution,
a declaration of the specialization is implicitly instantiated ([[temp.over]](temp.over "13.10.4Overload resolution"))[.](#10.sentence-1)
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L6755)
An implementation shall not implicitly instantiate a function template,
a variable template,
a member template, a non-virtual member function, a member class or
static data member of a templated class, or a substatement of a constexpr if
statement ([[stmt.if]](stmt.if "8.5.2The if statement")), unless such instantiation is required[.](#11.sentence-1)
[*Note [5](#note-5)*:
The instantiation of a generic lambda
does not require instantiation of
substatements of a constexpr if statement
within its [*compound-statement*](stmt.block#nt:compound-statement "8.4Compound statement or block[stmt.block]") unless the call operator template is instantiated[.](#11.sentence-2)
— *end note*]
It is unspecified whether or not an implementation implicitly instantiates a
virtual member function of a class template if the virtual member function would
not otherwise be instantiated[.](#11.sentence-3)
The use of a template specialization in
a default argument or default member initializer
shall not cause the template to be implicitly instantiated except
where needed to determine
the correctness of the default argument or default member initializer[.](#11.sentence-4)
The use of a default argument in a
function call causes specializations in the default argument to be implicitly
instantiated[.](#11.sentence-5)
Similarly, the use of a default member initializer
in a constructor definition or an aggregate initialization
causes specializations in the default member initializer to be instantiated[.](#11.sentence-6)
[12](#12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L6783)
If a templated functionf is called in a way that requires a default argument to be used,
the dependent names are looked up, the semantics constraints are checked,
and the instantiation of any template used in the default argument
is done as if the default argument had been
an initializer used in a function template specialization with the same scope,
the same template parameters and the same access as that of the function templatef used at that point, except that the scope in which a closure type is
declared ([[expr.prim.lambda.closure]](expr.prim.lambda.closure "7.5.6.2Closure types")) — and therefore its associated namespaces —
remain as determined from the context of the definition for the default
argument[.](#12.sentence-1)
This analysis is called[*default argument instantiation*](#def:default_argument_instantiation "13.9.2Implicit instantiation[temp.inst]")[.](#12.sentence-2)
The instantiated default argument is then used as the argument off[.](#12.sentence-3)
[13](#13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L6802)
Each default argument is instantiated independently[.](#13.sentence-1)
[*Example [8](#example-8)*: template<class T> void f(T x, T y = ydef(T()), T z = zdef(T()));
class A { };
A zdef(A);
void g(A a, A b, A c) { f(a, b, c); // no default argument instantiation f(a, b); // default argument z = zdef(T()) instantiated f(a); // error: ydef is not declared} — *end example*]
[14](#14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L6820)
The [*noexcept-specifier*](except.spec#nt:noexcept-specifier "14.5Exception specifications[except.spec]") and [*function-contract-specifier*](dcl.contract.func#nt:function-contract-specifier "9.4.1General[dcl.contract.func]")*s* of a function template specialization
are not instantiated along with the function declaration;
they are instantiated
when needed ([[except.spec]](except.spec "14.5Exception specifications"), [[dcl.contract.func]](dcl.contract.func "9.4.1General"))[.](#14.sentence-1)
If such a
specifier is needed but has not yet been
instantiated, the dependent names are looked up, the semantics constraints are
checked, and the instantiation of any template used in the
specifier is done as if it were being done as part
of instantiating the declaration of the specialization at that point[.](#14.sentence-2)
[15](#15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L6832)
[*Note [6](#note-6)*:
[[temp.point]](temp.point "13.8.4.1Point of instantiation") defines the point of instantiation of a template specialization[.](#15.sentence-1)
— *end note*]
[16](#16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L6837)
There is an implementation-defined quantity
that specifies the limit on the total depth of recursive instantiations ([[implimits]](implimits "Annex B(informative)Implementation quantities")),
which could involve more than one template[.](#16.sentence-1)
The result of an infinite recursion in instantiation is undefined[.](#16.sentence-2)
[*Example [9](#example-9)*: template<class T> class X { X<T>* p; // OK X<T*> a; // implicit generation of X<T> requires// the implicit instantiation of X<T*> which requires// the implicit instantiation of X<T**> which …}; — *end example*]
[17](#17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L6853)
The [*type-constraint*](temp.param#nt:type-constraint "13.2Template parameters[temp.param]")*s* and [*requires-clause*](temp.pre#nt:requires-clause "13.1Preamble[temp.pre]") of a template specialization or member function
are not instantiated along with the specialization or function itself,
even for a member function of a local class;
substitution into the atomic constraints formed from them is instead performed
as specified in [[temp.constr.decl]](temp.constr.decl "13.5.3Constrained declarations") and [[temp.constr.atomic]](temp.constr.atomic "13.5.2.3Atomic constraints") when determining whether the constraints are satisfied
or as specified in [[temp.constr.decl]](temp.constr.decl "13.5.3Constrained declarations") when comparing declarations[.](#17.sentence-1)
[*Note [7](#note-7)*:
The satisfaction of constraints is determined during
template argument deduction ([[temp.deduct]](temp.deduct "13.10.3Template argument deduction")) and
overload resolution ([[over.match]](over.match "12.2Overload resolution"))[.](#17.sentence-2)
— *end note*]
[*Example [10](#example-10)*: template<typename T> concept C = sizeof(T) > 2;template<typename T> concept D = C<T> && sizeof(T) > 4;
template<typename T> struct S { S() requires C<T> { } // #1 S() requires D<T> { } // #2};
S<char> s1; // error: no matching constructor S<char[8]> s2; // OK, calls #2
When S<char> is instantiated, both constructors are part of the
specialization[.](#17.sentence-3)
Their constraints are not satisfied, and
they suppress the implicit declaration of a default constructor forS<char> ([[class.default.ctor]](class.default.ctor "11.4.5.2Default constructors")), so there is no viable constructor
for s1[.](#17.sentence-4)
— *end example*]
[*Example [11](#example-11)*: template<typename T> struct S1 {template<typename U>requires falsestruct Inner1; // ill-formed, no diagnostic required};
template<typename T> struct S2 {template<typename U>requires (sizeof(T[-(int)sizeof(T)]) > 1)struct Inner2; // ill-formed, no diagnostic required};
The class S1<T>::Inner1 is ill-formed, no diagnostic required, because
it has no valid specializations[.](#17.sentence-5)
S2 is ill-formed, no diagnostic required, since no substitution into
the constraints of its Inner2 template would result in a valid
expression[.](#17.sentence-6)
— *end example*]