Files
2025-10-25 03:02:53 +03:00

1137 lines
59 KiB
Markdown
Raw Permalink 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.spec]
# 13 Templates [[temp]](./#temp)
## 13.9 Template instantiation and specialization [temp.spec]
### [13.9.1](#general) General [[temp.spec.general]](temp.spec.general)
[1](#general-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L6345)
The act of instantiating a function, a variable,
a class, a member of a class template, or
a member template is referred to as[*template instantiation*](#def:template_instantiation "13.9.1General[temp.spec.general]")[.](#general-1.sentence-1)
[2](#general-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L6352)
A function instantiated from a function template is called an instantiated
function[.](#general-2.sentence-1)
A class instantiated from a class template is called an instantiated class[.](#general-2.sentence-2)
A member function, a member class, a member enumeration, or a static data member of a class template
instantiated from the member definition of the class template is called,
respectively, an instantiated member function, member class, member enumeration, or static data
member[.](#general-2.sentence-3)
A member function instantiated from a member function template is called an
instantiated member function[.](#general-2.sentence-4)
A member class instantiated from a member class template is called an
instantiated member class[.](#general-2.sentence-5)
A variable instantiated from a variable template is called an
instantiated variable[.](#general-2.sentence-6)
A static data member instantiated from a static data member template
is called an instantiated static data member[.](#general-2.sentence-7)
[3](#general-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L6369)
An explicit specialization may be declared for a function template,
a variable template, a class template, a member of a class template, or
a member template[.](#general-3.sentence-1)
An explicit specialization declaration is introduced bytemplate<>[.](#general-3.sentence-2)
In an explicit specialization declaration for
a variable template, a class template,
a member of a class template, or a class member template,
the variable or class that is explicitly specialized
shall be specified with a [*simple-template-id*](temp.names#nt:simple-template-id "13.3Names of template specializations[temp.names]")[.](#general-3.sentence-3)
In the explicit specialization declaration for a function template or
a member function template,
the function or member function explicitly specialized may be specified
using a [*template-id*](temp.names#nt:template-id "13.3Names of template specializations[temp.names]")[.](#general-3.sentence-4)
[*Example [1](#general-example-1)*: template<class T = int> struct A {static int x;};template<class U> void g(U) { }template<> struct A<double> { }; // specialize for T == doubletemplate<> struct A<> { }; // specialize for T == inttemplate<> void g(char) { } // specialize for U == char// U is deduced from the parameter typetemplate<> void g<int>(int) { } // specialize for U == inttemplate<> int A<char>::x = 0; // specialize for T == chartemplate<class T = int> struct B {static int x;};template<> int B<>::x = 1; // specialize for T == int — *end example*]
[4](#general-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L6405)
An instantiated template specialization can be either implicitly
instantiated ([[temp.inst]](#temp.inst "13.9.2Implicit instantiation")) for a given argument list or be explicitly
instantiated ([[temp.explicit]](#temp.explicit "13.9.3Explicit instantiation"))[.](#general-4.sentence-1)
A [*specialization*](#def:specialization "13.9.1General[temp.spec.general]") is a class, variable, function, or class member that is either
instantiated ([[temp.inst]](#temp.inst "13.9.2Implicit instantiation")) from a templated entity or is an
explicit specialization ([[temp.expl.spec]](#temp.expl.spec "13.9.4Explicit specialization")) of a templated entity[.](#general-4.sentence-2)
[5](#general-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L6413)
For a given template and a given set of[*template-argument*](temp.names#nt:template-argument "13.3Names of template specializations[temp.names]")*s*,
- [(5.1)](#general-5.1)
an explicit instantiation definition shall appear at most once in a program,
- [(5.2)](#general-5.2)
an explicit specialization shall be defined at most once
in a program, as specified in [[basic.def.odr]](basic.def.odr "6.3One-definition rule"), and
- [(5.3)](#general-5.3)
both an explicit instantiation and a declaration of an
explicit specialization shall not appear in a program unless
the explicit specialization is reachable from the explicit instantiation[.](#general-5.sentence-1)
An implementation is not required to diagnose a violation of this rule
if neither declaration is reachable from the other[.](#general-5.sentence-2)
[6](#general-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L6430)
The usual access checking rules do not apply to names
in a declaration of an explicit instantiation or explicit specialization,
with the exception of names appearing in a function body,
default argument, [*base-clause*](class.derived.general#nt:base-clause "11.7.1General[class.derived.general]"), [*member-specification*](class.mem.general#nt:member-specification "11.4.1General[class.mem.general]"), [*enumerator-list*](dcl.enum#nt:enumerator-list "9.8.1Enumeration declarations[dcl.enum]"),
or static data member or variable template initializer[.](#general-6.sentence-1)
[*Note [1](#general-note-1)*:
In particular, the template arguments and names
used in the function declarator
(including parameter types, return types and exception specifications)
can be private types or objects that would normally not be accessible[.](#general-6.sentence-2)
— *end note*]
[7](#general-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L6443)
Each class template specialization instantiated from a template has its own
copy of any static members[.](#general-7.sentence-1)
[*Example [2](#general-example-2)*: template<class T> class X {static T s;};template<class T> T X<T>::s = 0;
X<int> aa;
X<char*> bb;
X<int> has a static members of typeint andX<char*> has a static members of typechar*[.](#general-7.sentence-2)
— *end example*]
[8](#general-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L6469)
If a function declaration acquired its function type through
a [dependent type](temp.dep.type "13.8.3.2Dependent types[temp.dep.type]") without using the syntactic form of
a function declarator, the program is ill-formed[.](#general-8.sentence-1)
[*Example [3](#general-example-3)*: template<class T> struct A {static T t;};typedef int function();
A<function> a; // error: would declare A<function>::t as a static member function — *end example*]
### [13.9.2](#temp.inst) Implicit instantiation [[temp.inst]](temp.inst)
[1](#temp.inst-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)](#temp.inst-1.1)
an inline function,
- [(1.2)](#temp.inst-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)](#temp.inst-1.3)
a potentially-constant variable ([[expr.const]](expr.const "7.7Constant expressions")), or
- [(1.4)](#temp.inst-1.4)
a specialization of a templated class[.](#temp.inst-1.sentence-1)
[*Note [1](#temp.inst-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"))[.](#temp.inst-1.sentence-2)
— *end note*]
[2](#temp.inst-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[.](#temp.inst-2.sentence-1)
[*Note [2](#temp.inst-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[.](#temp.inst-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[.](#temp.inst-2.sentence-3)
— *end note*]
[*Example [1](#temp.inst-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"))[.](#temp.inst-2.sentence-4)
[*Example [2](#temp.inst-example-2)*: template<class T> class X;
X<char> ch; // error: incomplete type X<char> — *end example*]
[*Note [3](#temp.inst-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*)[.](#temp.inst-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[.](#temp.inst-2.sentence-6)
— *end note*]
[3](#temp.inst-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L6564)
The implicit instantiation of a class template specialization causes
- [(3.1)](#temp.inst-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)](#temp.inst-3.2)
the implicit instantiation of the definitions of
deleted member functions,
unscoped member enumerations, and
member anonymous unions[.](#temp.inst-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[.](#temp.inst-3.sentence-2)
[*Example [3](#temp.inst-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[.](#temp.inst-3.sentence-3)
[*Example [4](#temp.inst-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[.](#temp.inst-3.sentence-4)
(It is not defined
but noted as being associated with a definition in Outer<T, U>[.](#temp.inst-3.sentence-5))
#2
is also a redeclaration of #1a[.](#temp.inst-3.sentence-6)
It is noted as associated with a definition,
so it is an invalid redeclaration of the same partial specialization[.](#temp.inst-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](#temp.inst-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[.](#temp.inst-4.sentence-1)
[5](#temp.inst-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[.](#temp.inst-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[.](#temp.inst-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[.](#temp.inst-5.sentence-3)
[*Note [4](#temp.inst-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[.](#temp.inst-5.sentence-4)
— *end note*]
[6](#temp.inst-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L6664)
[*Example [5](#temp.inst-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[.](#temp.inst-6.sentence-1)
— *end example*]
[7](#temp.inst-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[.](#temp.inst-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[.](#temp.inst-7.sentence-2)
[8](#temp.inst-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[.](#temp.inst-8.sentence-1)
[*Example [6](#temp.inst-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](#temp.inst-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[.](#temp.inst-9.sentence-1)
[*Example [7](#temp.inst-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](#temp.inst-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"))[.](#temp.inst-10.sentence-1)
[11](#temp.inst-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[.](#temp.inst-11.sentence-1)
[*Note [5](#temp.inst-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[.](#temp.inst-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[.](#temp.inst-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[.](#temp.inst-11.sentence-4)
The use of a default argument in a
function call causes specializations in the default argument to be implicitly
instantiated[.](#temp.inst-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[.](#temp.inst-11.sentence-6)
[12](#temp.inst-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[.](#temp.inst-12.sentence-1)
This analysis is called[*default argument instantiation*](#def:default_argument_instantiation "13.9.2Implicit instantiation[temp.inst]")[.](#temp.inst-12.sentence-2)
The instantiated default argument is then used as the argument off[.](#temp.inst-12.sentence-3)
[13](#temp.inst-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L6802)
Each default argument is instantiated independently[.](#temp.inst-13.sentence-1)
[*Example [8](#temp.inst-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](#temp.inst-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"))[.](#temp.inst-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[.](#temp.inst-14.sentence-2)
[15](#temp.inst-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L6832)
[*Note [6](#temp.inst-note-6)*:
[[temp.point]](temp.point "13.8.4.1Point of instantiation") defines the point of instantiation of a template specialization[.](#temp.inst-15.sentence-1)
— *end note*]
[16](#temp.inst-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[.](#temp.inst-16.sentence-1)
The result of an infinite recursion in instantiation is undefined[.](#temp.inst-16.sentence-2)
[*Example [9](#temp.inst-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](#temp.inst-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[.](#temp.inst-17.sentence-1)
[*Note [7](#temp.inst-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"))[.](#temp.inst-17.sentence-2)
— *end note*]
[*Example [10](#temp.inst-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[.](#temp.inst-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[.](#temp.inst-17.sentence-4)
— *end example*]
[*Example [11](#temp.inst-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[.](#temp.inst-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[.](#temp.inst-17.sentence-6)
— *end example*]
### [13.9.3](#temp.explicit) Explicit instantiation [[temp.explicit]](temp.explicit)
[1](#temp.explicit-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[.](#temp.explicit-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[.](#temp.explicit-1.sentence-2)
[2](#temp.explicit-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[.](#temp.explicit-2.sentence-2)
An explicit instantiation
declaration begins with the extern keyword[.](#temp.explicit-2.sentence-3)
[3](#temp.explicit-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[.](#temp.explicit-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[.](#temp.explicit-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[.](#temp.explicit-3.sentence-3)
[4](#temp.explicit-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]")[.](#temp.explicit-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]")[.](#temp.explicit-4.sentence-2)
[*Example [1](#temp.explicit-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](#temp.explicit-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"))[.](#temp.explicit-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[.](#temp.explicit-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[.](#temp.explicit-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[.](#temp.explicit-5.sentence-4)
[6](#temp.explicit-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[.](#temp.explicit-6.sentence-1)
[*Note [1](#temp.explicit-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")[.](#temp.explicit-6.sentence-2)
[*Example [2](#temp.explicit-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[.](#temp.explicit-6.sentence-3)
[7](#temp.explicit-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[.](#temp.explicit-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[.](#temp.explicit-7.sentence-2)
[8](#temp.explicit-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7021)
[*Note [2](#temp.explicit-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"))[.](#temp.explicit-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[.](#temp.explicit-8.sentence-2)
— *end note*]
[9](#temp.explicit-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[.](#temp.explicit-9.sentence-1)
[*Note [3](#temp.explicit-note-3)*:
In addition, it will typically be an explicit instantiation of certainimplementation-dependent data about the class[.](#temp.explicit-9.sentence-2)
— *end note*]
[10](#temp.explicit-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[.](#temp.explicit-10.sentence-1)
[11](#temp.explicit-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[.](#temp.explicit-11.sentence-1)
[12](#temp.explicit-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[.](#temp.explicit-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[.](#temp.explicit-12.sentence-2)
[*Note [4](#temp.explicit-note-4)*:
This rule does apply to inline functions even though an
explicit instantiation declaration of such an entity has no other normative
effect[.](#temp.explicit-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[.](#temp.explicit-12.sentence-4)
— *end note*]
An explicit instantiation declaration shall not name a specialization of a
template with internal linkage[.](#temp.explicit-12.sentence-5)
[13](#temp.explicit-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[.](#temp.explicit-13.sentence-1)
[*Example [3](#temp.explicit-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*]
### [13.9.4](#temp.expl.spec) Explicit specialization [[temp.expl.spec]](temp.expl.spec)
[1](#temp.expl.spec-1)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7093)
An explicit specialization of any of the following:
- [(1.1)](#temp.expl.spec-1.1)
function template
- [(1.2)](#temp.expl.spec-1.2)
class template
- [(1.3)](#temp.expl.spec-1.3)
variable template
- [(1.4)](#temp.expl.spec-1.4)
member function of a class template
- [(1.5)](#temp.expl.spec-1.5)
static data member of a class template
- [(1.6)](#temp.expl.spec-1.6)
member class of a class template
- [(1.7)](#temp.expl.spec-1.7)
member enumeration of a class template
- [(1.8)](#temp.expl.spec-1.8)
member class template of a class or class template
- [(1.9)](#temp.expl.spec-1.9)
member function template of a class or class template
can be declared by a declaration introduced bytemplate<>;
that is:
[explicit-specialization:](#nt:explicit-specialization "13.9.4Explicit specialization[temp.expl.spec]")
template < > [*declaration*](dcl.pre#nt:declaration "9.1Preamble[dcl.pre]")
[*Example [1](#temp.expl.spec-example-1)*: template<class T> class stream;
template<> class stream<char> { /* ... */ }; // #1template<class T> class Array { /* ... */ };template<class T> void sort(Array<T>& v) { /* ... */ }template<> void sort<int>(Array<int>&); // #2template<> void sort(Array<char*>&); // #3 template argument is deduced ([[temp.arg.explicit]](temp.arg.explicit "13.10.2Explicit template argument specification"))
Given these declarations,
#1 will be used as the definition of streams ofchars;
other streams will be handled by class template specializations instantiated
from the class template[.](#temp.expl.spec-1.sentence-2)
Similarly,
#2 will be used as the sort function for arguments of
type Array<int> and
#3 will be used for arguments
of typeArray<char*>;
otherArray types will be sorted by functions generated from the function template[.](#temp.expl.spec-1.sentence-3)
— *end example*]
[2](#temp.expl.spec-2)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7155)
The [*declaration*](dcl.pre#nt:declaration "9.1Preamble[dcl.pre]") in an [*explicit-specialization*](#nt:explicit-specialization "13.9.4Explicit specialization[temp.expl.spec]") shall not be an [*export-declaration*](module.interface#nt:export-declaration "10.2Export declaration[module.interface]")[.](#temp.expl.spec-2.sentence-1)
An explicit specialization 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[.](#temp.expl.spec-2.sentence-2)
[3](#temp.expl.spec-3)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7162)
An explicit specialization
may be declared in any scope in which the corresponding primary template
may be defined ([[dcl.meaning]](dcl.meaning "9.3.4Meaning of declarators"), [[class.mem]](class.mem "11.4Class members"), [[temp.mem]](temp.mem "13.7.3Member templates"))[.](#temp.expl.spec-3.sentence-1)
[4](#temp.expl.spec-4)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7167)
An explicit specialization does not introduce a name ([[basic.scope.scope]](basic.scope.scope "6.4.1General"))[.](#temp.expl.spec-4.sentence-1)
A declaration of a function template, class template, or variable template being explicitly
specialized shall be reachable from the declaration of
the explicit specialization[.](#temp.expl.spec-4.sentence-2)
[*Note [1](#temp.expl.spec-note-1)*:
A declaration, but not a definition of the template is needed[.](#temp.expl.spec-4.sentence-3)
— *end note*]
The definition of a class or class template shall be reachable from the
declaration of an explicit specialization for a member template of the class
or class template[.](#temp.expl.spec-4.sentence-4)
[*Example [2](#temp.expl.spec-example-2)*: template<> class X<int> { /* ... */ }; // error: X not a templatetemplate<class T> class X;
template<> class X<char*> { /* ... */ }; // OK, X is a template — *end example*]
[5](#temp.expl.spec-5)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7188)
A member function, a member function template, a member class,
a member enumeration, a
member class template,
a static data member, or a static data member template of a class template
may be explicitly specialized for a class specialization that is implicitly
instantiated;
in this case, the definition of the class template shall
be reachable from the explicit specialization for the member of the class
template[.](#temp.expl.spec-5.sentence-1)
If such an explicit specialization for the member of a class template names an
implicitly-declared special member function ([[special]](special "11.4.4Special member functions")),
the program is ill-formed[.](#temp.expl.spec-5.sentence-2)
[6](#temp.expl.spec-6)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7202)
A member of an explicitly specialized class is not implicitly
instantiated from the member declaration of the class template;
instead, the member of the class template specialization shall itself be
explicitly defined if its definition is required[.](#temp.expl.spec-6.sentence-1)
The definition of the class template explicit specialization
shall be reachable from the definition of any member of it[.](#temp.expl.spec-6.sentence-2)
The definition of an explicitly specialized class is unrelated to the
definition of a generated specialization[.](#temp.expl.spec-6.sentence-3)
That is, its members need
not have the same names, types, etc. as the members of a generated
specialization[.](#temp.expl.spec-6.sentence-4)
Members of an explicitly specialized
class template are defined in the same manner as members of normal classes, and
not using the template<> syntax[.](#temp.expl.spec-6.sentence-5)
The same is true when defining a member of an explicitly specialized member
class[.](#temp.expl.spec-6.sentence-6)
However, template<> is used in defining a member of an explicitly
specialized member class template that is specialized as a class template[.](#temp.expl.spec-6.sentence-7)
[*Example [3](#temp.expl.spec-example-3)*: template<class T> struct A {struct B { }; template<class U> struct C { };};
template<> struct A<int> {void f(int);};
void h() { A<int> a;
a.f(16); // A<int>::f must be defined somewhere}// template<> not used for a member of an explicitly specialized class templatevoid A<int>::f(int) { /* ... */ }template<> struct A<char>::B {void f();};// template<> also not used when defining a member of an explicitly specialized member classvoid A<char>::B::f() { /* ... */ }template<> template<class U> struct A<char>::C {void f();};// template<> is used when defining a member of an explicitly specialized member class template// specialized as a class templatetemplate<>template<class U> void A<char>::C<U>::f() { /* ... */ }template<> struct A<short>::B {void f();};template<> void A<short>::B::f() { /* ... */ } // error: template<> not permittedtemplate<> template<class U> struct A<short>::C {void f();};template<class U> void A<short>::C<U>::f() { /* ... */ } // error: template<> required — *end example*]
[7](#temp.expl.spec-7)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7265)
If a template, a member template or a member of a class template is explicitly
specialized, a declaration of that specialization shall be reachable from
every use of
that specialization that would cause an implicit instantiation to take place,
in every translation unit in which such a use occurs;
no diagnostic is required[.](#temp.expl.spec-7.sentence-1)
If the program does not provide a definition for an explicit specialization and
either the specialization is used in a way that would cause an implicit
instantiation to take place or the member is a virtual member function,
the program is ill-formed, no diagnostic required[.](#temp.expl.spec-7.sentence-2)
An implicit instantiation is never generated for an explicit specialization
that is declared but not defined[.](#temp.expl.spec-7.sentence-3)
[*Example [4](#temp.expl.spec-example-4)*: class String { };template<class T> class Array { /* ... */ };template<class T> void sort(Array<T>& v) { /* ... */ }void f(Array<String>& v) { sort(v); // use primary template sort(Array<T>&), T is String}template<> void sort<String>(Array<String>& v); // error: specialization after use of primary templatetemplate<> void sort<>(Array<char*>& v); // OK, sort<char*> not yet usedtemplate<class T> struct A {enum E : T; enum class S : T;};template<> enum A<int>::E : int { eint }; // OKtemplate<> enum class A<int>::S : int { sint }; // OKtemplate<class T> enum A<T>::E : T { eT };template<class T> enum class A<T>::S : T { sT };template<> enum A<char>::E : char { echar }; // error: A<char>::E was instantiated// when A<char> was instantiatedtemplate<> enum class A<char>::S : char { schar }; // OK — *end example*]
[8](#temp.expl.spec-8)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7304)
The placement of explicit specialization declarations for function templates, class
templates, variable templates,
member functions of class templates, static data members of class
templates, member classes of class templates, member enumerations of class
templates, member class templates of class
templates, member function templates of class templates,
static data member templates of class templates,
member functions of
member templates of class templates, member functions of member templates of
non-template classes,
static data member templates of non-template classes,
member function templates of member classes of class
templates, etc., and the placement of partial specialization declarations
of class templates, variable templates,
member class templates of non-template classes,
static data member templates of non-template classes, member
class templates of class templates, etc., can affect whether a program is
well-formed according to the relative positioning of the explicit specialization
declarations and their points of instantiation in the translation unit as
specified above and below[.](#temp.expl.spec-8.sentence-1)
When writing a specialization, be careful about its location;
or to make it compile will be such a trial as to kindle its self-immolation[.](#temp.expl.spec-8.sentence-2)
[9](#temp.expl.spec-9)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7328)
[*Note [2](#temp.expl.spec-note-2)*:
A class template explicit specialization that has been declared but
not defined can be used exactly like other
incompletely-defined classes ([[basic.types]](basic.types "6.9Types"))[.](#temp.expl.spec-9.sentence-1)
[*Example [5](#temp.expl.spec-example-5)*: template<class T> class X; // X is a class templatetemplate<> class X<int>;
X<int>* p; // OK, pointer to declared class X<int> X<int> x; // error: object of incomplete class X<int> — *end example*]
— *end note*]
[10](#temp.expl.spec-10)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7344)
[*Note [3](#temp.expl.spec-note-3)*:
An explicit specialization of a constrained template needs
to satisfy that template's associated constraints ([[temp.constr.decl]](temp.constr.decl "13.5.3Constrained declarations"))[.](#temp.expl.spec-10.sentence-1)
The satisfaction of constraints is determined
when forming the template name of an explicit specialization
in which all template arguments are specified ([[temp.names]](temp.names "13.3Names of template specializations")),
or, for explicit specializations 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[.](#temp.expl.spec-10.sentence-2)
— *end note*]
[11](#temp.expl.spec-11)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7356)
A function with the same name as a template and a type that exactly matches that
of a template specialization is not an explicit specialization ([[temp.fct]](temp.fct "13.7.7Function templates"))[.](#temp.expl.spec-11.sentence-1)
[12](#temp.expl.spec-12)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7360)
Whether an explicit specialization of a function or variable template
is inline, constexpr, constinit, or consteval
is determined by the explicit specialization and
is independent of those properties of the template[.](#temp.expl.spec-12.sentence-1)
Similarly,
attributes and [*function-contract-specifier*](dcl.contract.func#nt:function-contract-specifier "9.4.1General[dcl.contract.func]")*s* appearing in the declaration of a template
have no effect on an explicit specialization of that template[.](#temp.expl.spec-12.sentence-2)
[*Example [6](#temp.expl.spec-example-6)*: template<class T> void f(T) { /* ... */ }template<class T> inline T g(T) { /* ... */ }template<> inline void f<>(int) { /* ... */ } // OK, inlinetemplate<> int g<>(int) { /* ... */ } // OK, not inlinetemplate<typename> [[noreturn]] void h([[maybe_unused]] int i);template<> void h<int>(int i) {// Implementations are expected not to warn that the function returns// but can warn about the unused parameter.} — *end example*]
[13](#temp.expl.spec-13)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7385)
An explicit specialization of a static data member of a template
or an explicit specialization of a static data member template is a
definition if the declaration includes an initializer;
otherwise, it is a declaration[.](#temp.expl.spec-13.sentence-1)
[*Note [4](#temp.expl.spec-note-4)*:
The definition of a static data member of a template
for which default-initialization is desired
can use functional cast notation ([[expr.type.conv]](expr.type.conv "7.6.1.4Explicit type conversion (functional notation)")):template<> X Q<int>::x; // declarationtemplate<> X Q<int>::x (); // error: declares a functiontemplate<> X Q<int>::x = X(); // definition
— *end note*]
[14](#temp.expl.spec-14)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7401)
A member or a member template of a class template may be explicitly specialized
for a given implicit instantiation of the class template, even if the member
or member template is defined in the class template definition[.](#temp.expl.spec-14.sentence-1)
An explicit specialization of a member or member template is specified using the
syntax for explicit specialization[.](#temp.expl.spec-14.sentence-2)
[*Example [7](#temp.expl.spec-example-7)*: template<class T> struct A {void f(T); template<class X1> void g1(T, X1); template<class X2> void g2(T, X2); void h(T) { }};
// specializationtemplate<> void A<int>::f(int);
// out of class member template definitiontemplate<class T> template<class X1> void A<T>::g1(T, X1) { }// member template specializationtemplate<> template<class X1> void A<int>::g1(int, X1);
// member template specializationtemplate<> template<>void A<int>::g1(int, char); // X1 deduced as chartemplate<> template<>void A<int>::g2<char>(int, char); // X2 specified as char// member specialization even if defined in class definitiontemplate<> void A<int>::h(int) { } — *end example*]
[15](#temp.expl.spec-15)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7436)
A member or a member template may be nested within many enclosing class
templates[.](#temp.expl.spec-15.sentence-1)
In an explicit specialization for such a member,
the member declaration shall be preceded by atemplate<> for each enclosing class template that is explicitly specialized[.](#temp.expl.spec-15.sentence-2)
[*Example [8](#temp.expl.spec-example-8)*: template<class T1> class A {template<class T2> class B {void mf(); };};template<> template<> class A<int>::B<double>;template<> template<> void A<char>::B<char>::mf(); — *end example*]
[16](#temp.expl.spec-16)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7455)
In an explicit specialization declaration for a member of a class template or
a member template that appears in namespace scope,
the member template and some of its enclosing class templates may remain
unspecialized,
except that the declaration shall not explicitly specialize a class member
template if its enclosing class templates are not explicitly specialized
as well[.](#temp.expl.spec-16.sentence-1)
In such an explicit specialization declaration, the keywordtemplate followed by a[*template-parameter-list*](temp.pre#nt:template-parameter-list "13.1Preamble[temp.pre]") shall be provided instead of thetemplate<> preceding the explicit specialization declaration of the member[.](#temp.expl.spec-16.sentence-2)
The types of the[*template-parameter*](temp.param#nt:template-parameter "13.2Template parameters[temp.param]")*s* in the[*template-parameter-list*](temp.pre#nt:template-parameter-list "13.1Preamble[temp.pre]") shall be the same as those specified in the primary template definition[.](#temp.expl.spec-16.sentence-3)
[*Example [9](#temp.expl.spec-example-9)*: template <class T1> class A {template<class T2> class B {template<class T3> void mf1(T3); void mf2(); };};template <> template <class X>class A<int>::B {template <class T> void mf1(T); };template <> template <> template<class T>void A<int>::B<double>::mf1(T t) { }template <class Y> template <>void A<Y>::B<double>::mf2() { } // error: B<double> is specialized but// its enclosing class template A is not — *end example*]
[17](#temp.expl.spec-17)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7495)
A specialization of a member function template, member class template,
or static data member template of
a non-specialized class template is itself a template[.](#temp.expl.spec-17.sentence-1)
[18](#temp.expl.spec-18)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7500)
An explicit specialization declaration shall not be a friend declaration[.](#temp.expl.spec-18.sentence-1)
[19](#temp.expl.spec-19)
[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7503)
Default function arguments shall not be specified in a declaration or
a definition for one of the following explicit specializations:
- [(19.1)](#temp.expl.spec-19.1)
the explicit specialization of a function template;
- [(19.2)](#temp.expl.spec-19.2)
the explicit specialization of a member function template;
- [(19.3)](#temp.expl.spec-19.3)
the explicit specialization of a member function of a class template where
the class template specialization to which the member function specialization
belongs is implicitly instantiated[.](#temp.expl.spec-19.sentence-1)
[*Note [5](#temp.expl.spec-note-5)*:
Default function arguments can be specified in the declaration or
definition of a member function of a class template specialization that is
explicitly specialized[.](#temp.expl.spec-19.3.sentence-2)
— *end note*]