215 lines
12 KiB
Markdown
215 lines
12 KiB
Markdown
[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.3 Explicit instantiation [temp.explicit]")
|
||
externopt template [*declaration*](dcl.pre#nt:declaration "9.1 Preamble [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.2 Storage class specifiers [dcl.stc]") ([[dcl.stc]](dcl.stc "9.2.2 Storage 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.1 Attribute syntax and semantics [dcl.attr.grammar]") ([[dcl.attr.grammar]](dcl.attr.grammar "9.13.1 Attribute 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.5 Elaborated type specifiers [dcl.type.elab]") in the [*declaration*](dcl.pre#nt:declaration "9.1 Preamble [dcl.pre]") shall include a [*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]");
|
||
otherwise, the [*declaration*](dcl.pre#nt:declaration "9.1 Preamble [dcl.pre]") shall be a [*simple-declaration*](dcl.pre#nt:simple-declaration "9.1 Preamble [dcl.pre]") whose [*init-declarator-list*](dcl.decl.general#nt:init-declarator-list "9.3.1 General [dcl.decl.general]") comprises a single [*init-declarator*](dcl.decl.general#nt:init-declarator "9.3.1 General [dcl.decl.general]") that does not have an [*initializer*](dcl.init.general#nt:initializer "9.5.1 General [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.2 Unqualified names [expr.prim.id.unqual]") in the [*declarator*](dcl.decl.general#nt:declarator "9.3.1 General [dcl.decl.general]") shall be a [*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names 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.2 Explicit 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.1 General"))[.](#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.1 Preamble [dcl.pre]") of the explicit instantiation names an implicitly-declared special member
|
||
function ([[special]](special "11.4.4 Special 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.1 Preamble [dcl.pre]") in an [*explicit-instantiation*](#nt:explicit-instantiation "13.9.3 Explicit instantiation [temp.explicit]") and
|
||
the [*declaration*](dcl.pre#nt:declaration "9.1 Preamble [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.7 Program and linkage"), except as specified in [[except.spec]](except.spec "14.5 Exception 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.7 Placeholder type specifiers")) â *end example*]
|
||
|
||
â *end note*]
|
||
|
||
Despite its syntactic form, the [*declaration*](dcl.pre#nt:declaration "9.1 Preamble [dcl.pre]") in an [*explicit-instantiation*](#nt:explicit-instantiation "13.9.3 Explicit 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.3 Constrained 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.3 Names of template specializations")),
|
||
or, for explicit instantiations of function templates,
|
||
during template argument deduction ([[temp.deduct.decl]](temp.deduct.decl "13.10.3.7 Deducing 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.3 Constrained declarations"), [[temp.constr.constr]](temp.constr.constr "13.5.2 Constraints")),
|
||
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.7 Destructors"))
|
||
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.2 Implicit 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*]
|