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

215 lines
12 KiB
Markdown
Raw 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.explicit]
# 13 Templates [[temp]](./#temp)
## 13.9 Template instantiation and specialization [[temp.spec]](temp.spec#temp.explicit)
### 13.9.3 Explicit instantiation [temp.explicit]
[1](#1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L6909)
A class, function, variable, or member template specialization can be explicitly
instantiated from its template[.](#1.sentence-1)
A member function, member class or static data member of a class template can
be explicitly instantiated from the member definition associated with its class
template[.](#1.sentence-2)
[2](#2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L6918)
The syntax for explicit instantiation is:
[explicit-instantiation:](#nt:explicit-instantiation "13.9.3Explicit instantiation[temp.explicit]")
externopt template [*declaration*](dcl.pre#nt:declaration "9.1Preamble[dcl.pre]")
There are two forms of explicit instantiation: an explicit instantiation
definition and an explicit instantiation declaration[.](#2.sentence-2)
An explicit instantiation
declaration begins with the extern keyword[.](#2.sentence-3)
[3](#3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L6929)
An explicit instantiation shall not use
a [*storage-class-specifier*](dcl.stc#nt:storage-class-specifier "9.2.2Storage class specifiers[dcl.stc]") ([[dcl.stc]](dcl.stc "9.2.2Storage class specifiers"))
other than thread_local[.](#3.sentence-1)
An explicit instantiation of a
function template,
member function of a class template, or
variable template
shall not
use the inline, constexpr, or consteval specifiers[.](#3.sentence-2)
No [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1Attribute syntax and semantics[dcl.attr.grammar]") ([[dcl.attr.grammar]](dcl.attr.grammar "9.13.1Attribute syntax and semantics"))
shall appertain to an explicit instantiation[.](#3.sentence-3)
[4](#4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L6942)
If the explicit instantiation is for a class or member class, the[*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5Elaborated type specifiers[dcl.type.elab]") in the [*declaration*](dcl.pre#nt:declaration "9.1Preamble[dcl.pre]") shall include a [*simple-template-id*](temp.names#nt:simple-template-id "13.3Names of template specializations[temp.names]");
otherwise, the [*declaration*](dcl.pre#nt:declaration "9.1Preamble[dcl.pre]") shall be a [*simple-declaration*](dcl.pre#nt:simple-declaration "9.1Preamble[dcl.pre]") whose [*init-declarator-list*](dcl.decl.general#nt:init-declarator-list "9.3.1General[dcl.decl.general]") comprises a single [*init-declarator*](dcl.decl.general#nt:init-declarator "9.3.1General[dcl.decl.general]") that does not have an [*initializer*](dcl.init.general#nt:initializer "9.5.1General[dcl.init.general]")[.](#4.sentence-1)
If the explicit instantiation is for a variable template specialization,
the [*unqualified-id*](expr.prim.id.unqual#nt:unqualified-id "7.5.5.2Unqualified names[expr.prim.id.unqual]") in the [*declarator*](dcl.decl.general#nt:declarator "9.3.1General[dcl.decl.general]") shall be a [*simple-template-id*](temp.names#nt:simple-template-id "13.3Names of template specializations[temp.names]")[.](#4.sentence-2)
[*Example [1](#example-1)*: template<class T> class Array { void mf(); };template class Array<char>;template void Array<int>::mf();
template<class T> void sort(Array<T>& v) { /* ... */ }template void sort(Array<char>&); // argument is deduced here ([[temp.arg.explicit]](temp.arg.explicit "13.10.2Explicit template argument specification"))namespace N {template<class T> void f(T&) { }}template void N::f<int>(int&); — *end example*]
[5](#5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L6969)
An explicit instantiation does not introduce a name ([[basic.scope.scope]](basic.scope.scope "6.4.1General"))[.](#5.sentence-1)
A declaration of a function template, a variable template, a member function
or static data member
of a class template, or a member function template of a class or class
template shall be reachable from any explicit instantiation of that entity[.](#5.sentence-2)
A definition
of a class template, a member class of a class template, or a member class
template of a class or class template shall be reachable from any explicit instantiation
of that entity unless an explicit
specialization of the entity with the same template arguments
is reachable therefrom[.](#5.sentence-3)
If the [*declaration*](dcl.pre#nt:declaration "9.1Preamble[dcl.pre]") of the explicit instantiation names an implicitly-declared special member
function ([[special]](special "11.4.4Special member functions")), the program is ill-formed[.](#5.sentence-4)
[6](#6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L6985)
The [*declaration*](dcl.pre#nt:declaration "9.1Preamble[dcl.pre]") in an [*explicit-instantiation*](#nt:explicit-instantiation "13.9.3Explicit instantiation[temp.explicit]") and
the [*declaration*](dcl.pre#nt:declaration "9.1Preamble[dcl.pre]") produced by the corresponding substitution
into the templated function, variable, or class
are two declarations of the same entity[.](#6.sentence-1)
[*Note [1](#note-1)*:
These declarations need to have matching types as specified in [[basic.link]](basic.link "6.7Program and linkage"), except as specified in [[except.spec]](except.spec "14.5Exception specifications")[.](#6.sentence-2)
[*Example [2](#example-2)*: template<typename T> T var = {};template float var<float>; // OK, instantiated variable has type floattemplate int var<int[16]>[]; // OK, absence of major array bound is permittedtemplate int *var<int>; // error: instantiated variable has type inttemplate<typename T> auto av = T();template int av<int>; // OK, variable with type int can be redeclared with type autotemplate<typename T> auto f() {}template void f<int>(); // error: function with deduced return type// redeclared with non-deduced return type ([[dcl.spec.auto]](dcl.spec.auto "9.2.9.7Placeholder type specifiers")) — *end example*]
— *end note*]
Despite its syntactic form, the [*declaration*](dcl.pre#nt:declaration "9.1Preamble[dcl.pre]") in an [*explicit-instantiation*](#nt:explicit-instantiation "13.9.3Explicit instantiation[temp.explicit]") for a variable is not itself a definition and does not conflict with the definition instantiated by an explicit instantiation definition for that variable[.](#6.sentence-3)
[7](#7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7010)
For a given set of template arguments, if an explicit
instantiation of a template appears after a declaration of
an explicit specialization for that template, the explicit
instantiation has no effect[.](#7.sentence-1)
Otherwise, for an explicit instantiation
definition, the definition of a
function template, a variable template, a member
function template, or a member function or static
data member of a class template shall be present in every
translation unit in which it is explicitly instantiated[.](#7.sentence-2)
[8](#8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7021)
[*Note [2](#note-2)*:
An explicit instantiation of a constrained template needs
to satisfy that template's associated constraints ([[temp.constr.decl]](temp.constr.decl "13.5.3Constrained declarations"))[.](#8.sentence-1)
The satisfaction of constraints is determined
when forming the template name of an explicit instantiation
in which all template arguments are specified ([[temp.names]](temp.names "13.3Names of template specializations")),
or, for explicit instantiations of function templates,
during template argument deduction ([[temp.deduct.decl]](temp.deduct.decl "13.10.3.7Deducing template arguments from a function declaration"))
when one or more trailing template arguments are left unspecified[.](#8.sentence-2)
— *end note*]
[9](#9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7034)
An explicit instantiation that names a class
template specialization is also an explicit
instantiation of the same kind (declaration or definition) of each
of its direct non-template members
that has not been previously explicitly specialized in
the translation unit containing the explicit instantiation,
provided that the associated constraints, if any,
of that member are satisfied by the template arguments of the explicit
instantiation ([[temp.constr.decl]](temp.constr.decl "13.5.3Constrained declarations"), [[temp.constr.constr]](temp.constr.constr "13.5.2Constraints")),
except as described below[.](#9.sentence-1)
[*Note [3](#note-3)*:
In addition, it will typically be an explicit instantiation of certainimplementation-dependent data about the class[.](#9.sentence-2)
— *end note*]
[10](#10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7051)
An explicit instantiation definition that names a class template
specialization explicitly instantiates the class template specialization
and is an explicit instantiation definition of only those
members that have been defined at the point of instantiation[.](#10.sentence-1)
[11](#11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7057)
An explicit instantiation of a prospective destructor ([[class.dtor]](class.dtor "11.4.7Destructors"))
shall correspond to the selected destructor of the class[.](#11.sentence-1)
[12](#12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7061)
If an entity is the subject of both an explicit instantiation declaration
and an explicit instantiation definition in the same translation unit, the
definition shall follow the declaration[.](#12.sentence-1)
An entity that is the subject of an
explicit instantiation declaration and that is also used
in a way that would otherwise cause an [implicit instantiation](temp.inst "13.9.2Implicit instantiation[temp.inst]") in the translation unit
shall be the subject of an explicit instantiation definition somewhere in the
program; otherwise the program is ill-formed, no diagnostic required[.](#12.sentence-2)
[*Note [4](#note-4)*:
This rule does apply to inline functions even though an
explicit instantiation declaration of such an entity has no other normative
effect[.](#12.sentence-3)
This is needed to ensure that if the address of an inline function is
taken in a translation unit in which the implementation chose to suppress the
out-of-line body, another translation unit will supply the body[.](#12.sentence-4)
— *end note*]
An explicit instantiation declaration shall not name a specialization of a
template with internal linkage[.](#12.sentence-5)
[13](#13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7080)
An explicit instantiation does not constitute a use of a default argument,
so default argument instantiation is not done[.](#13.sentence-1)
[*Example [3](#example-3)*: char* p = 0;template<class T> T g(T x = &p) { return x; }template int g<int>(int); // OK even though &p isn't an int. — *end example*]