13 Templates [temp]

13.1 Preamble [temp.pre]

The declaration in a template-declaration (if any) shall
  • declare or define a function, a class, or a variable, or
  • define a member function, a member class, a member enumeration, or a static data member of a class template or of a class nested within a class template, or
  • define a member template of a class or class template, or
  • be a deduction-guide, or
  • be an alias-declaration.
A declaration introduced by a template declaration of a variable is a variable template.
A variable template at class scope is a static data member template.
[Example 1: template<class T> constexpr T pi = T(3.1415926535897932385L); template<class T> T circular_area(T r) { return pi<T> * r * r; } struct matrix_constants { template<class T> using pauli = hermitian_matrix<T, 2>; template<class T> constexpr static pauli<T> sigma1 = { { 0, 1 }, { 1, 0 } }; template<class T> constexpr static pauli<T> sigma2 = { { 0, -1i }, { 1i, 0 } }; template<class T> constexpr static pauli<T> sigma3 = { { 1, 0 }, { 0, -1 } }; }; — end example]
[Note 2:
A template-declaration can appear only as a namespace scope or class scope declaration.
— end note]
Its declaration shall not be an export-declaration.
In a function template declaration, the unqualified-id of the declarator-id shall be a name.
[Note 3:
A class or variable template declaration of a simple-template-id declares a partial specialization ([temp.spec.partial]).
— end note]
In a template-declaration, explicit specialization, or explicit instantiation the init-declarator-list in the declaration shall contain at most one declarator.
When such a declaration is used to declare a class template, no declarator is permitted.
A specialization (explicit or implicit) of one template is distinct from all specializations of any other template.
A template, an explicit specialization ([temp.expl.spec]), and a partial specialization shall not have C language linkage.
[Note 4:
Default arguments for function templates and for member functions of class templates are considered definitions for the purpose of template instantiation ([temp.decls]) and must obey the one-definition rule ([basic.def.odr]).
— end note]
[Note 5:
A template cannot have the same name as any other name bound in the same scope ([basic.scope.scope]), except that a function template can share a name with non-template functions ([dcl.fct]) and/or function templates ([temp.over]).
Specializations, including partial specializations ([temp.spec.partial]), do not reintroduce or bind names.
Their target scope is the target scope of the primary template, so all specializations of a template belong to the same scope as it does.
— end note]
An entity is templated if it is
[Note 6:
A local class, a local or block variable, or a friend function defined in a templated entity is a templated entity.
— end note]
A template-declaration is written in terms of its template parameters.
The optional requires-clause following a template-parameter-list allows the specification of constraints ([temp.constr.decl]) on template arguments ([temp.arg]).
The requires-clause introduces the constraint-expression that results from interpreting the constraint-logical-or-expression as a constraint-expression.
[Note 7:
The expression in a requires-clause uses a restricted grammar to avoid ambiguities.
Parentheses can be used to specify arbitrary expressions in a requires-clause.
[Example 2: template<int N> requires N == sizeof new unsigned short int f(); // error: parentheses required around == expression — end example]
— end note]
A definition of a function template, member function of a class template, variable template, or static data member of a class template shall be reachable from the end of every definition domain ([basic.def.odr]) in which it is implicitly instantiated ([temp.inst]) unless the corresponding specialization is explicitly instantiated ([temp.explicit]) in some translation unit; no diagnostic is required.

13.2 Template parameters [temp.param]

There is no semantic difference between class and typename in a type-parameter-key.
typename followed by an unqualified-id names a template type parameter.
typename followed by a qualified-id denotes the type in a non-type120 parameter-declaration.
[Example 1: class T { /* ... */ }; int i; template<class T, T i> void f(T t) { T t1 = i; // template-parameters T and i ::T t2 = ::i; // global namespace members T and i }
Here, the template f has a type-parameter called T, rather than an unnamed non-type template-parameter of class T.
— end example]
A storage class shall not be specified in a template-parameter declaration.
Types shall not be defined in a template-parameter declaration.
The identifier in a type-parameter is not looked up.
A type-parameter whose identifier does not follow an ellipsis defines its identifier to be a typedef-name (if declared without template) or template-name (if declared with template) in the scope of the template declaration.
[Note 2:
A template argument can be a class template or alias template.
For example,
template<class T> class myarray { /* ... */ }; template<class K, class V, template<class T> class C = myarray> class Map { C<K> key; C<V> value; }; — end note]
A type-constraint Q that designates a concept C can be used to constrain a contextually-determined type or template type parameter pack T with a constraint-expression E defined as follows.
If Q is of the form C<A, , A>, then let E be C<T, A, , A>.
Otherwise, let E be C<T>.
If T is not a pack, then E is E, otherwise E is (E && ...).
The concept designated by a type-constraint shall be a type concept ([temp.concept]).
A type-parameter that starts with a type-constraint introduces the immediately-declared constraint of the type-constraint for the parameter.
[Example 2: template<typename T> concept C1 = true; template<typename... Ts> concept C2 = true; template<typename T, typename U> concept C3 = true; template<C1 T> struct s1; // associates C1<T> template<C1... T> struct s2; // associates (C1<T> && ...) template<C2... T> struct s3; // associates (C2<T> && ...) template<C3<int> T> struct s4; // associates C3<T, int> template<C3<int>... T> struct s5; // associates (C3<T, int> && ...) — end example]
A non-type template-parameter shall have one of the following (possibly cv-qualified) types:
The top-level cv-qualifiers on the template-parameter are ignored when determining its type.
A structural type is one of the following:
  • a scalar type, or
  • an lvalue reference type, or
  • a literal class type with the following properties:
    • all base classes and non-static data members are public and non-mutable and
    • the types of all bases classes and non-static data members are structural types or (possibly multi-dimensional) array thereof.
An id-expression naming a non-type template-parameter of class type T denotes a static storage duration object of type const T, known as a template parameter object, whose value is that of the corresponding template argument after it has been converted to the type of the template-parameter.
All such template parameters in the program of the same type with the same value denote the same template parameter object.
A template parameter object shall have constant destruction ([expr.const]).
[Note 3:
If an id-expression names a non-type non-reference template-parameter, then it is a prvalue if it has non-class type.
Otherwise, if it is of class type T, it is an lvalue and has type const T ([expr.prim.id.unqual]).
— end note]
[Example 3: using X = int; struct A {}; template<const X& x, int i, A a> void f() { i++; // error: change of template-parameter value &x; // OK &i; // error: address of non-reference template-parameter &a; // OK int& ri = i; // error: non-const reference bound to temporary const int& cri = i; // OK: const reference bound to temporary const A& ra = a; // OK: const reference bound to a template parameter object } — end example]
[Note 4:
A non-type template-parameter cannot be declared to have type cv void.
[Example 4: template<void v> class X; // error template<void* pv> class Y; // OK — end example]
— end note]
A non-type template-parameter of type “array of T” or of function type T is adjusted to be of type “pointer to T.
[Example 5: template<int* a> struct R { /* ... */ }; template<int b[5]> struct S { /* ... */ }; int p; R<&p> w; // OK S<&p> x; // OK due to parameter adjustment int v[5]; R<v> y; // OK due to implicit argument conversion S<v> z; // OK due to both adjustment and conversion — end example]
A non-type template parameter declared with a type that contains a placeholder type with a type-constraint introduces the immediately-declared constraint of the type-constraint for the invented type corresponding to the placeholder ([dcl.fct]).
A default template-argument may be specified for any kind of template-parameter (type, non-type, template) that is not a template parameter pack.
A default template-argument may be specified in a template declaration.
A default template-argument shall not be specified in the template-parameter-lists of the definition of a member of a class template that appears outside of the member's class.
A default template-argument shall not be specified in a friend class template declaration.
If a friend function template declaration D specifies a default template-argument, that declaration shall be a definition and there shall be no other declaration of the function template which is reachable from D or from which D is reachable.
The set of default template-arguments available for use is obtained by merging the default arguments from all prior declarations of the template in the same way default function arguments are ([dcl.fct.default]).
[Example 6:
template<class T1, class T2 = int> class A; template<class T1 = int, class T2> class A; is equivalent to template<class T1 = int, class T2 = int> class A;
— end example]
If a template-parameter of a class template, variable template, or alias template has a default template-argument, each subsequent template-parameter shall either have a default template-argument supplied or be a template parameter pack.
If a template-parameter of a primary class template, primary variable template, or alias template is a template parameter pack, it shall be the last template-parameter.
A template parameter pack of a function template shall not be followed by another template parameter unless that template parameter can be deduced from the parameter-type-list ([dcl.fct]) of the function template or has a default argument ([temp.deduct]).
A template parameter of a deduction guide template ([temp.deduct.guide]) that does not have a default argument shall be deducible from the parameter-type-list of the deduction guide template.
[Example 7: template<class T1 = int, class T2> class B; // error // U can be neither deduced from the parameter-type-list nor specified template<class... T, class... U> void f() { } // error template<class... T, class U> void g() { } // error — end example]
A template-parameter shall not be given default arguments by two different declarations if one is reachable from the other.
[Example 8: template<class T = int> class X; template<class T = int> class X { /* ... */ }; // error — end example]
When parsing a default template-argument for a non-type template-parameter, the first non-nested > is taken as the end of the template-parameter-list rather than a greater-than operator.
[Example 9: template<int i = 3 > 4 > // syntax error class X { /* ... */ }; template<int i = (3 > 4) > // OK class Y { /* ... */ }; — end example]
A template-parameter of a template template-parameter is permitted to have a default template-argument.
When such default arguments are specified, they apply to the template template-parameter in the scope of the template template-parameter.
[Example 10: template <template <class TT = float> class T> struct A { inline void f(); inline void g(); }; template <template <class TT> class T> void A<T>::f() { T<> t; // error: TT has no default template argument } template <template <class TT = char> class T> void A<T>::g() { T<> t; // OK, T<char> } — end example]
If a template-parameter is a type-parameter with an ellipsis prior to its optional identifier or is a parameter-declaration that declares a pack ([dcl.fct]), then the template-parameter is a template parameter pack.
A template parameter pack that is a parameter-declaration whose type contains one or more unexpanded packs is a pack expansion.
Similarly, a template parameter pack that is a type-parameter with a template-parameter-list containing one or more unexpanded packs is a pack expansion.
A type parameter pack with a type-constraint that contains an unexpanded parameter pack is a pack expansion.
A template parameter pack that is a pack expansion shall not expand a template parameter pack declared in the same template-parameter-list.
[Example 11: template <class... Types> // Types is a template type parameter pack class Tuple; // but not a pack expansion template <class T, int... Dims> // Dims is a non-type template parameter pack struct multi_array; // but not a pack expansion template <class... T> struct value_holder { template <T... Values> struct apply { }; // Values is a non-type template parameter pack }; // and a pack expansion template <class... T, T... Values> // error: Values expands template type parameter struct static_array; // pack T within the same template parameter list — end example]
120)120)
Since template template-parameters and template template-arguments are treated as types for descriptive purposes, the terms non-type parameter and non-type argument are used to refer to non-type, non-template parameters and arguments.

13.3 Names of template specializations [temp.names]

The component name of a simple-template-id, template-id, or template-name is the first name in it.
A < is interpreted as the delimiter of a template-argument-list if it follows a name that is not a conversion-function-id and
[Note 1:
If the name is an identifier, it is then interpreted as a template-name.
The keyword template is used to indicate that a dependent qualified name ([temp.dep.type]) denotes a template where an expression might appear.
— end note]
[Example 1: struct X { template<std::size_t> X* alloc(); template<std::size_t> static X* adjust(); }; template<class T> void f(T* p) { T* p1 = p->alloc<200>(); // error: < means less than T* p2 = p->template alloc<200>(); // OK: < starts template argument list T::adjust<100>(); // error: < means less than T::template adjust<100>(); // OK: < starts template argument list } — end example]
When parsing a template-argument-list, the first non-nested >121 is taken as the ending delimiter rather than a greater-than operator.
Similarly, the first non-nested >> is treated as two consecutive but distinct > tokens, the first of which is taken as the end of the template-argument-list and completes the template-id.
[Note 2:
The second > token produced by this replacement rule can terminate an enclosing template-id construct or it can be part of a different construct (e.g., a cast).
— end note]
[Example 2: template<int i> class X { /* ... */ }; X< 1>2 > x1; // syntax error X<(1>2)> x2; // OK template<class T> class Y { /* ... */ }; Y<X<1>> x3; // OK, same as Y<X<1> > x3; Y<X<6>>1>> x4; // syntax error Y<X<(6>>1)>> x5; // OK — end example]
The keyword template shall not appear immediately after a declarative nested-name-specifier ([expr.prim.id.qual]).
A name prefixed by the keyword template shall be followed by a template argument list or refer to a class template or an alias template.
The latter case is deprecated ([depr.template.template]).
The keyword template shall not appear immediately before a ~ token (as to name a destructor).
[Note 3:
The keyword template cannot be applied to non-template members of class templates.
— end note]
[Note 4:
As is the case with the typename prefix, the template prefix is allowed even when lookup for the name would already find a template.
— end note]
[Example 3: template <class T> struct A { void f(int); template <class U> void f(U); }; template <class T> void f(T t) { A<T> a; a.template f<>(t); // OK: calls template a.template f(t); // error: not a template-id } template <class T> struct B { template <class T2> struct C { }; }; // deprecated: T​::​C is assumed to name a class template: template <class T, template <class X> class TT = T::template C> struct D { }; D<B<int> > db; — end example]
A template-id is valid if
A simple-template-id shall be valid unless it names a function template specialization ([temp.deduct]).
[Example 4: template<class T, T::type n = 0> class X; struct S { using type = int; }; using T1 = X<S, int, int>; // error: too many arguments using T2 = X<>; // error: no default argument for first template parameter using T3 = X<1>; // error: value 1 does not match type-parameter using T4 = X<int>; // error: substitution failure for second template parameter using T5 = X<S>; // OK — end example]
When the template-name of a simple-template-id names a constrained non-function template or a constrained template template-parameter, and all template-arguments in the simple-template-id are non-dependent ([temp.dep.temp]), the associated constraints ([temp.constr.decl]) of the constrained template shall be satisfied ([temp.constr.constr]).
[Example 5: template<typename T> concept C1 = sizeof(T) != sizeof(int); template<C1 T> struct S1 { }; template<C1 T> using Ptr = T*; S1<int>* p; // error: constraints not satisfied Ptr<int> p; // error: constraints not satisfied template<typename T> struct S2 { Ptr<int> x; }; // ill-formed, no diagnostic required template<typename T> struct S3 { Ptr<T> x; }; // OK, satisfaction is not required S3<int> x; // error: constraints not satisfied template<template<C1 T> class X> struct S4 { X<int> x; // ill-formed, no diagnostic required }; template<typename T> concept C2 = sizeof(T) == 1; template<C2 T> struct S { }; template struct S<char[2]>; // error: constraints not satisfied template<> struct S<char[2]> { }; // error: constraints not satisfied — end example]
A concept-id is a prvalue of type bool, and does not name a template specialization.
A concept-id evaluates to true if the concept's normalized constraint-expression ([temp.constr.decl]) is satisfied ([temp.constr.constr]) by the specified template arguments and false otherwise.
[Note 5:
Since a constraint-expression is an unevaluated operand, a concept-id appearing in a constraint-expression is not evaluated except as necessary to determine whether the normalized constraints are satisfied.
— end note]
[Example 6: template<typename T> concept C = true; static_assert(C<int>); // OK — end example]
121)121)
A > that encloses the type-id of a dynamic_­cast, static_­cast, reinterpret_­cast or const_­cast, or which encloses the template-arguments of a subsequent template-id, is considered nested for the purpose of this description.

13.4 Template arguments [temp.arg]

13.4.1 General [temp.arg.general]

There are three forms of template-argument, corresponding to the three forms of template-parameter: type, non-type and template.
The type and form of each template-argument specified in a template-id shall match the type and form specified for the corresponding parameter declared by the template in its template-parameter-list.
When the parameter declared by the template is a template parameter pack, it will correspond to zero or more template-arguments.
[Example 1: template<class T> class Array { T* v; int sz; public: explicit Array(int); T& operator[](int); T& elem(int i) { return v[i]; } }; Array<int> v1(20); typedef std::complex<double> dcomplex; // std​::​complex is a standard library template Array<dcomplex> v2(30); Array<dcomplex> v3(40); void bar() { v1[3] = 7; v2[3] = v3.elem(4) = dcomplex(7,8); } — end example]
The template argument list of a template-head is a template argument list in which the template argument has the value of the template parameter of the template-head.
If the template parameter is a template parameter pack ([temp.variadic]), the template argument is a pack expansion whose pattern is the name of the template parameter pack.
In a template-argument, an ambiguity between a type-id and an expression is resolved to a type-id, regardless of the form of the corresponding template-parameter.122
[Example 2: template<class T> void f(); template<int I> void f(); void g() { f<int()>(); // int() is a type-id: call the first f() } — end example]
[Note 1:
Names used in a template-argument are subject to access control where they appear.
Because a template-parameter is not a class member, no access control applies.
— end note]
[Example 3: template<class T> class X { static T t; }; class Y { private: struct S { /* ... */ }; X<S> x; // OK: S is accessible // X<Y​::​S> has a static member of type Y​::​S // OK: even though Y​::​S is private }; X<Y::S> y; // error: S not accessible — end example]
For a template-argument that is a class type or a class template, the template definition has no special access rights to the members of the template-argument.
[Example 4: template <template <class TT> class T> class A { typename T<int>::S s; }; template <class U> class B { private: struct S { /* ... */ }; }; A<B> b; // error: A has no access to B​::​S — end example]
When template argument packs or default template-arguments are used, a template-argument list can be empty.
In that case the empty <> brackets shall still be used as the template-argument-list.
[Example 5: template<class T = char> class String; String<>* p; // OK: String<char> String* q; // syntax error template<class ... Elements> class Tuple; Tuple<>* t; // OK: Elements is empty Tuple* u; // syntax error — end example]
An explicit destructor call ([class.dtor]) for an object that has a type that is a class template specialization may explicitly specify the template-arguments.
[Example 6: template<class T> struct A { ~A(); }; void f(A<int>* p, A<int>* q) { p->A<int>::~A(); // OK: destructor call q->A<int>::~A<int>(); // OK: destructor call } — end example]
If the use of a template-argument gives rise to an ill-formed construct in the instantiation of a template specialization, the program is ill-formed.
When name lookup for the component name of a template-id finds an overload set, both non-template functions in the overload set and function templates in the overload set for which the template-arguments do not match the template-parameters are ignored.
[Note 2:
If none of the function templates have matching template-parameters, the program is ill-formed.
— end note]
When a simple-template-id does not name a function, a default template-argument is implicitly instantiated when the value of that default argument is needed.
[Example 7: template<typename T, typename U = int> struct S { }; S<bool>* p; // the type of p is S<bool, int>*
The default argument for U is instantiated to form the type S<bool, int>*.
— end example]
A template-argument followed by an ellipsis is a pack expansion.
122)122)
There is no such ambiguity in a default template-argument because the form of the template-parameter determines the allowable forms of the template-argument.

13.4.2 Template type arguments [temp.arg.type]

A template-argument for a template-parameter which is a type shall be a type-id.
[Example 1: template <class T> class X { }; template <class T> void f(T t) { } struct { } unnamed_obj; void f() { struct A { }; enum { e1 }; typedef struct { } B; B b; X<A> x1; // OK X<A*> x2; // OK X<B> x3; // OK f(e1); // OK f(unnamed_obj); // OK f(b); // OK } — end example]
[Note 1:
A template type argument can be an incomplete type ([basic.types]).
— end note]

13.4.3 Template non-type arguments [temp.arg.nontype]

If the type T of a template-parameter ([temp.param]) contains a placeholder type ([dcl.spec.auto]) or a placeholder for a deduced class type ([dcl.type.class.deduct]), the type of the parameter is the type deduced for the variable x in the invented declaration T x = template-argument ;
If a deduced parameter type is not permitted for a template-parameter declaration ([temp.param]), the program is ill-formed.
A template-argument for a non-type template-parameter shall be a converted constant expression ([expr.const]) of the type of the template-parameter.
[Note 1:
If the template-argument is an overload set (or the address of such, including forming a pointer-to-member), the matching function is selected from the set ([over.over]).
— end note]
For a non-type template-parameter of reference or pointer type, or for each non-static data member of reference or pointer type in a non-type template-parameter of class type or subobject thereof, the reference or pointer value shall not refer to or be the address of (respectively):
[Example 1: template<const int* pci> struct X { /* ... */ }; int ai[10]; X<ai> xi; // array to pointer and qualification conversions struct Y { /* ... */ }; template<const Y& b> struct Z { /* ... */ }; Y y; Z<y> z; // no conversion, but note extra cv-qualification template<int (&pa)[5]> struct W { /* ... */ }; int b[5]; W<b> w; // no conversion void f(char); void f(int); template<void (*pf)(int)> struct A { /* ... */ }; A<&f> a; // selects f(int) template<auto n> struct B { /* ... */ }; B<5> b1; // OK, template parameter type is int B<'a'> b2; // OK, template parameter type is char B<2.5> b3; // OK, template parameter type is double B<void(0)> b4; // error: template parameter type cannot be void — end example]
[Note 2:
A string-literal ([lex.string]) is not an acceptable template-argument for a template-parameter of non-class type.
[Example 2: template<class T, T p> class X { /* ... */ }; X<const char*, "Studebaker"> x; // error: string literal object as template-argument X<const char*, "Knope" + 1> x2; // error: subobject of string literal object as template-argument const char p[] = "Vivisectionist"; X<const char*, p> y; // OK struct A { constexpr A(const char*) {} }; X<A, "Pyrophoricity"> z; // OK, string-literal is a constructor argument to A — end example]
— end note]
[Note 3:
A temporary object is not an acceptable template-argument when the corresponding template-parameter has reference type.
[Example 3: template<const int& CRI> struct B { /* ... */ }; B<1> b1; // error: temporary would be required for template argument int c = 1; B<c> b2; // OK struct X { int n; }; struct Y { const int &r; }; template<Y y> struct C { /* ... */ }; C<Y{X{1}.n}> c; // error: subobject of temporary object used to initialize // reference member of template parameter — end example]
— end note]

13.4.4 Template template arguments [temp.arg.template]

A template-argument for a template template-parameter shall be the name of a class template or an alias template, expressed as id-expression.
Only primary templates are considered when matching the template template argument with the corresponding parameter; partial specializations are not considered even if their parameter lists match that of the template template parameter.
Any partial specializations ([temp.spec.partial]) associated with the primary template are considered when a specialization based on the template template-parameter is instantiated.
If a specialization is not reachable from the point of instantiation, and it would have been selected had it been reachable, the program is ill-formed, no diagnostic required.
[Example 1: template<class T> class A { // primary template int x; }; template<class T> class A<T*> { // partial specialization long x; }; template<template<class U> class V> class C { V<int> y; V<int*> z; }; C<A> c; // V<int> within C<A> uses the primary template, so c.y.x has type int // V<int*> within C<A> uses the partial specialization, so c.z.x has type long — end example]
A template-argument matches a template template-parameter P when P is at least as specialized as the template-argument A.
In this comparison, if P is unconstrained, the constraints on A are not considered.
If P contains a template parameter pack, then A also matches P if each of A's template parameters matches the corresponding template parameter in the template-head of P.
Two template parameters match if they are of the same kind (type, non-type, template), for non-type template-parameters, their types are equivalent ([temp.over.link]), and for template template-parameters, each of their corresponding template-parameters matches, recursively.
When P's template-head contains a template parameter pack ([temp.variadic]), the template parameter pack will match zero or more template parameters or template parameter packs in the template-head of A with the same type and form as the template parameter pack in P (ignoring whether those template parameters are template parameter packs).
[Example 2: template<class T> class A { /* ... */ }; template<class T, class U = T> class B { /* ... */ }; template<class ... Types> class C { /* ... */ }; template<auto n> class D { /* ... */ }; template<template<class> class P> class X { /* ... */ }; template<template<class ...> class Q> class Y { /* ... */ }; template<template<int> class R> class Z { /* ... */ }; X<A> xa; // OK X<B> xb; // OK X<C> xc; // OK Y<A> ya; // OK Y<B> yb; // OK Y<C> yc; // OK Z<D> zd; // OK — end example]
[Example 3: template <class T> struct eval; template <template <class, class...> class TT, class T1, class... Rest> struct eval<TT<T1, Rest...>> { }; template <class T1> struct A; template <class T1, class T2> struct B; template <int N> struct C; template <class T1, int N> struct D; template <class T1, class T2, int N = 17> struct E; eval<A<int>> eA; // OK: matches partial specialization of eval eval<B<int, float>> eB; // OK: matches partial specialization of eval eval<C<17>> eC; // error: C does not match TT in partial specialization eval<D<int, 17>> eD; // error: D does not match TT in partial specialization eval<E<int, float>> eE; // error: E does not match TT in partial specialization — end example]
[Example 4: template<typename T> concept C = requires (T t) { t.f(); }; template<typename T> concept D = C<T> && requires (T t) { t.g(); }; template<template<C> class P> struct S { }; template<C> struct X { }; template<D> struct Y { }; template<typename T> struct Z { }; S<X> s1; // OK, X and P have equivalent constraints S<Y> s2; // error: P is not at least as specialized as Y S<Z> s3; // OK, P is at least as specialized as Z — end example]
A template template-parameter P is at least as specialized as a template template-argument A if, given the following rewrite to two function templates, the function template corresponding to P is at least as specialized as the function template corresponding to A according to the partial ordering rules for function templates.
Given an invented class template X with the template-head of A (including default arguments and requires-clause, if any):
  • Each of the two function templates has the same template parameters and requires-clause (if any), respectively, as P or A.
  • Each function template has a single function parameter whose type is a specialization of X with template arguments corresponding to the template parameters from the respective function template where, for each template parameter PP in the template-head of the function template, a corresponding template argument AA is formed.
    If PP declares a template parameter pack, then AA is the pack expansion PP... ([temp.variadic]); otherwise, AA is the id-expression PP.
If the rewrite produces an invalid type, then P is not at least as specialized as A.

13.5 Template constraints [temp.constr]

13.5.1 General [temp.constr.general]

[Note 1:
Subclause [temp.constr] defines the meaning of constraints on template arguments.
The abstract syntax and satisfaction rules are defined in [temp.constr.constr].
Constraints are associated with declarations in [temp.constr.decl].
Declarations are partially ordered by their associated constraints ([temp.constr.order]).
— end note]

13.5.2 Constraints [temp.constr.constr]

13.5.2.1 General [temp.constr.constr.general]

A constraint is a sequence of logical operations and operands that specifies requirements on template arguments.
The operands of a logical operation are constraints.
There are three different kinds of constraints:
In order for a constrained template to be instantiated ([temp.spec]), its associated constraints shall be satisfied as described in the following subclauses.
[Note 1:
Forming the name of a specialization of a class template, a variable template, or an alias template ([temp.names]) requires the satisfaction of its constraints.
Overload resolution requires the satisfaction of constraints on functions and function templates.
— end note]

13.5.2.2 Logical operations [temp.constr.op]

There are two binary logical operations on constraints: conjunction and disjunction.
[Note 1:
These logical operations have no corresponding C++ syntax.
For the purpose of exposition, conjunction is spelled using the symbol and disjunction is spelled using the symbol .
The operands of these operations are called the left and right operands.
In the constraint , A is the left operand, and B is the right operand.
— end note]
A conjunction is a constraint taking two operands.
To determine if a conjunction is satisfied, the satisfaction of the first operand is checked.
If that is not satisfied, the conjunction is not satisfied.
Otherwise, the conjunction is satisfied if and only if the second operand is satisfied.
A disjunction is a constraint taking two operands.
To determine if a disjunction is satisfied, the satisfaction of the first operand is checked.
If that is satisfied, the disjunction is satisfied.
Otherwise, the disjunction is satisfied if and only if the second operand is satisfied.
[Example 1: template<typename T> constexpr bool get_value() { return T::value; } template<typename T> requires (sizeof(T) > 1) && (get_value<T>()) void f(T); // has associated constraint sizeof(T) > 1 get_­value<T>() void f(int); f('a'); // OK: calls f(int)
In the satisfaction of the associated constraints of f, the constraint sizeof(char) > 1 is not satisfied; the second operand is not checked for satisfaction.
— end example]
[Note 2:
A logical negation expression ([expr.unary.op]) is an atomic constraint; the negation operator is not treated as a logical operation on constraints.
As a result, distinct negation constraint-expressions that are equivalent under [temp.over.link] do not subsume one another under [temp.constr.order].
Furthermore, if substitution to determine whether an atomic constraint is satisfied ([temp.constr.atomic]) encounters a substitution failure, the constraint is not satisfied, regardless of the presence of a negation operator.
[Example 2: template <class T> concept sad = false; template <class T> int f1(T) requires (!sad<T>); template <class T> int f1(T) requires (!sad<T>) && true; int i1 = f1(42); // ambiguous, !sad<T> atomic constraint expressions ([temp.constr.atomic]) // are not formed from the same expression template <class T> concept not_sad = !sad<T>; template <class T> int f2(T) requires not_sad<T>; template <class T> int f2(T) requires not_sad<T> && true; int i2 = f2(42); // OK, !sad<T> atomic constraint expressions both come from not_­sad template <class T> int f3(T) requires (!sad<typename T::type>); int i3 = f3(42); // error: associated constraints not satisfied due to substitution failure template <class T> concept sad_nested_type = sad<typename T::type>; template <class T> int f4(T) requires (!sad_nested_type<T>); int i4 = f4(42); // OK, substitution failure contained within sad_­nested_­type
Here, requires (!sad<typename T​::​type>) requires that there is a nested type that is not sad, whereas requires (!sad_­nested_­type<T>) requires that there is no sad nested type.
— end example]
— end note]

13.5.2.3 Atomic constraints [temp.constr.atomic]

An atomic constraint is formed from an expression E and a mapping from the template parameters that appear within E to template arguments that are formed via substitution during constraint normalization in the declaration of a constrained entity (and, therefore, can involve the unsubstituted template parameters of the constrained entity), called the parameter mapping ([temp.constr.decl]).
[Note 1:
Atomic constraints are formed by constraint normalization.
— end note]
Two atomic constraints, and , are identical if they are formed from the same appearance of the same expression and if, given a hypothetical template A whose template-parameter-list consists of template-parameters corresponding and equivalent ([temp.over.link]) to those mapped by the parameter mappings of the expression, a template-id naming A whose template-arguments are the targets of the parameter mapping of is the same ([temp.type]) as a template-id naming A whose template-arguments are the targets of the parameter mapping of .
[Note 2:
The comparison of parameter mappings of atomic constraints operates in a manner similar to that of declaration matching with alias template substitution ([temp.alias]).
[Example 1: template <unsigned N> constexpr bool Atomic = true; template <unsigned N> concept C = Atomic<N>; template <unsigned N> concept Add1 = C<N + 1>; template <unsigned N> concept AddOne = C<N + 1>; template <unsigned M> void f() requires Add1<2 * M>; template <unsigned M> int f() requires AddOne<2 * M> && true; int x = f<0>(); // OK, the atomic constraints from concept C in both fs are Atomic<N> // with mapping similar to template <unsigned N> struct WrapN; template <unsigned N> using Add1Ty = WrapN<N + 1>; template <unsigned N> using AddOneTy = WrapN<N + 1>; template <unsigned M> void g(Add1Ty<2 * M> *); template <unsigned M> void g(AddOneTy<2 * M> *); void h() { g<0>(nullptr); // OK, there is only one g } — end example]
This similarity includes the situation where a program is ill-formed, no diagnostic required, when the meaning of the program depends on whether two constructs are equivalent, and they are functionally equivalent but not equivalent.
[Example 2: template <unsigned N> void f2() requires Add1<2 * N>; template <unsigned N> int f2() requires Add1<N * 2> && true; void h2() { f2<0>(); // ill-formed, no diagnostic required: // requires determination of subsumption between atomic constraints that are // functionally equivalent but not equivalent } — end example]
— end note]
To determine if an atomic constraint is satisfied, the parameter mapping and template arguments are first substituted into its expression.
If substitution results in an invalid type or expression, the constraint is not satisfied.
Otherwise, the lvalue-to-rvalue conversion is performed if necessary, and E shall be a constant expression of type bool.
The constraint is satisfied if and only if evaluation of E results in true.
If, at different points in the program, the satisfaction result is different for identical atomic constraints and template arguments, the program is ill-formed, no diagnostic required.
[Example 3: template<typename T> concept C = sizeof(T) == 4 && !true; // requires atomic constraints sizeof(T) == 4 and !true template<typename T> struct S { constexpr operator bool() const { return true; } }; template<typename T> requires (S<T>{}) void f(T); // #1 void f(int); // #2 void g() { f(0); // error: expression S<int>{} does not have type bool } // while checking satisfaction of deduced arguments of #1; // call is ill-formed even though #2 is a better match — end example]

13.5.3 Constrained declarations [temp.constr.decl]

A template declaration ([temp.pre]) or templated function declaration ([dcl.fct]) can be constrained by the use of a requires-clause.
This allows the specification of constraints for that declaration as an expression:
Constraints can also be associated with a declaration through the use of type-constraints in a template-parameter-list or parameter-type-list.
Each of these forms introduces additional constraint-expressions that are used to constrain the declaration.
A declaration's associated constraints are defined as follows:
The formation of the associated constraints establishes the order in which constraints are instantiated when checking for satisfaction ([temp.constr.constr]).
[Example 1: template<typename T> concept C = true; template<C T> void f1(T); template<typename T> requires C<T> void f2(T); template<typename T> void f3(T) requires C<T>;
The functions f1, f2, and f3 have the associated constraint C<T>.
template<typename T> concept C1 = true; template<typename T> concept C2 = sizeof(T) > 0; template<C1 T> void f4(T) requires C2<T>; template<typename T> requires C1<T> && C2<T> void f5(T);
The associated constraints of f4 and f5 are C1<T> C2<T>.
template<C1 T> requires C2<T> void f6(); template<C2 T> requires C1<T> void f7();
The associated constraints of f6 are C1<T> C2<T>, and those of f7 are C2<T> C1<T>.
— end example]
When determining whether a given introduced constraint-expression of a declaration in an instantiated specialization of a templated class is equivalent ([temp.over.link]) to the corresponding constraint-expression of a declaration outside the class body, is instantiated.
If the instantiation results in an invalid expression, the constraint-expressions are not equivalent.
[Note 1:
This can happen when determining which member template is specialized by an explicit specialization declaration.
— end note]
[Example 2: template <class T> concept C = true; template <class T> struct A { template <class U> U f(U) requires C<typename T::type>; // #1 template <class U> U f(U) requires C<T>; // #2 }; template <> template <class U> U A<int>::f(U u) requires C<int> { return u; } // OK, specializes #2
Substituting int for T in C<typename T​::​type> produces an invalid expression, so the specialization does not match #1.
Substituting int for T in C<T> produces C<int>, which is equivalent to the constraint-expression for the specialization, so it does match #2.
— end example]

13.5.4 Constraint normalization [temp.constr.normal]

The normal form of an expression E is a constraint that is defined as follows:
  • The normal form of an expression ( E ) is the normal form of E.
  • The normal form of an expression E1 || E2 is the disjunction of the normal forms of E1 and E2.
  • The normal form of an expression E1 && E2 is the conjunction of the normal forms of E1 and E2.
  • The normal form of a concept-id C<A, A, ..., A> is the normal form of the constraint-expression of C, after substituting A, A, ..., A for C's respective template parameters in the parameter mappings in each atomic constraint.
    If any such substitution results in an invalid type or expression, the program is ill-formed; no diagnostic is required.
    [Example 1: template<typename T> concept A = T::value || true; template<typename U> concept B = A<U*>; template<typename V> concept C = B<V&>;
    Normalization of B's constraint-expression is valid and results in T​::​value (with the mapping ) true (with an empty mapping), despite the expression T​::​value being ill-formed for a pointer type T.
    Normalization of C's constraint-expression results in the program being ill-formed, because it would form the invalid type V&* in the parameter mapping.
    — end example]
  • The normal form of any other expression E is the atomic constraint whose expression is E and whose parameter mapping is the identity mapping.
The process of obtaining the normal form of a constraint-expression is called normalization.
[Note 1:
Normalization of constraint-expressions is performed when determining the associated constraints ([temp.constr.constr]) of a declaration and when evaluating the value of an id-expression that names a concept specialization ([expr.prim.id]).
— end note]
[Example 2: template<typename T> concept C1 = sizeof(T) == 1; template<typename T> concept C2 = C1<T> && 1 == 2; template<typename T> concept C3 = requires { typename T::type; }; template<typename T> concept C4 = requires (T x) { ++x; } template<C2 U> void f1(U); // #1 template<C3 U> void f2(U); // #2 template<C4 U> void f3(U); // #3
The associated constraints of #1 are sizeof(T) == 1 (with mapping ) 1 == 2.

The associated constraints of #2 are requires { typename T​::​type; } (with mapping ).

The associated constraints of #3 are requires (T x) { ++x; } (with mapping ).
— end example]

13.5.5 Partial ordering by constraints [temp.constr.order]

A constraint P subsumes a constraint Q if and only if, for every disjunctive clause in the disjunctive normal form123 of P, subsumes every conjunctive clause in the conjunctive normal form124 of Q, where
  • a disjunctive clause subsumes a conjunctive clause if and only if there exists an atomic constraint in for which there exists an atomic constraint in such that subsumes , and
  • an atomic constraint A subsumes another atomic constraint B if and only if A and B are identical using the rules described in [temp.constr.atomic].
[Example 1:
Let A and B be atomic constraints.
The constraint subsumes A, but A does not subsume .
The constraint A subsumes , but does not subsume A.
Also note that every constraint subsumes itself.
— end example]
[Note 1:
The subsumption relation defines a partial ordering on constraints.
This partial ordering is used to determine
— end note]
A declaration D1 is at least as constrained as a declaration D2 if
  • D1 and D2 are both constrained declarations and D1's associated constraints subsume those of D2; or
  • D2 has no associated constraints.
A declaration D1 is more constrained than another declaration D2 when D1 is at least as constrained as D2, and D2 is not at least as constrained as D1.
[Example 2: template<typename T> concept C1 = requires(T t) { --t; }; template<typename T> concept C2 = C1<T> && requires(T t) { *t; }; template<C1 T> void f(T); // #1 template<C2 T> void f(T); // #2 template<typename T> void g(T); // #3 template<C1 T> void g(T); // #4 f(0); // selects #1 f((int*)0); // selects #2 g(true); // selects #3 because C1<bool> is not satisfied g(0); // selects #4 — end example]
123)123)
A constraint is in disjunctive normal form when it is a disjunction of clauses where each clause is a conjunction of atomic constraints.
For atomic constraints A, B, and C, the disjunctive normal form of the constraint is .
Its disjunctive clauses are and .
124)124)
A constraint is in conjunctive normal form when it is a conjunction of clauses where each clause is a disjunction of atomic constraints.
For atomic constraints A, B, and C, the constraint is in conjunctive normal form.
Its conjunctive clauses are A and .

13.6 Type equivalence [temp.type]

Two template-ids are the same if
Two template-ids that are the same refer to the same class, function, or variable.
Two values are template-argument-equivalent if they are of the same type and
  • they are of integral type and their values are the same, or
  • they are of floating-point type and their values are identical, or
  • they are of type std​::​nullptr_­t, or
  • they are of enumeration type and their values are the same,125 or
  • they are of pointer type and they have the same pointer value, or
  • they are of pointer-to-member type and they refer to the same class member or are both the null member pointer value, or
  • they are of reference type and they refer to the same object or function, or
  • they are of array type and their corresponding elements are template-argument-equivalent,126 or
  • they are of union type and either they both have no active member or they have the same active member and their active members are template-argument-equivalent, or
  • they are of class type and their corresponding direct subobjects and reference members are template-argument-equivalent.
[Example 1:
template<class E, int size> class buffer { /* ... */ }; buffer<char,2*512> x; buffer<char,1024> y; declares x and y to be of the same type, and template<class T, void(*err_fct)()> class list { /* ... */ }; list<int,&error_handler1> x1; list<int,&error_handler2> x2; list<int,&error_handler2> x3; list<char,&error_handler2> x4; declares x2 and x3 to be of the same type.
Their type differs from the types of x1 and x4.
template<class T> struct X { }; template<class> struct Y { }; template<class T> using Z = Y<T>; X<Y<int> > y; X<Z<int> > z; declares y and z to be of the same type.
— end example]
If an expression e is type-dependent, decltype(e) denotes a unique dependent type.
Two such decltype-specifiers refer to the same type only if their expressions are equivalent ([temp.over.link]).
[Note 1:
However, such a type might be aliased, e.g., by a typedef-name.
— end note]
125)125)
The identity of enumerators is not preserved.
126)126)
An array as a template-parameter decays to a pointer.

13.7 Template declarations [temp.decls]

13.7.1 General [temp.decls.general]

The template parameters of a template are specified in the angle bracket enclosed list that immediately follows the keyword template.
A primary template declaration is one in which the name of the template is not followed by a template-argument-list.
The template argument list of a primary template is the template argument list of its template-head ([temp.arg]).
A template declaration in which the name of the template is followed by a template-argument-list is a partial specialization ([temp.spec.partial]) of the template named in the declaration, which shall be a class or variable template.
For purposes of name lookup and instantiation, default arguments, type-constraints, requires-clauses ([temp.pre]), and noexcept-specifiers of function templates and of member functions of class templates are considered definitions; each default argument, type-constraint, requires-clause, or noexcept-specifier is a separate definition which is unrelated to the templated function definition or to any other default arguments type-constraints, requires-clauses, or noexcept-specifiers.
For the purpose of instantiation, the substatements of a constexpr if statement are considered definitions.
Because an alias-declaration cannot declare a template-id, it is not possible to partially or explicitly specialize an alias template.

13.7.2 Class templates [temp.class]

13.7.2.1 General [temp.class.general]

A class template defines the layout and operations for an unbounded set of related types.
[Example 1:
It is possible for a single class template List to provide an unbounded set of class definitions: one class List<T> for every type T, each describing a linked list of elements of type T.
Similarly, a class template Array describing a contiguous, dynamic array can be defined like this: template<class T> class Array { T* v; int sz; public: explicit Array(int); T& operator[](int); T& elem(int i) { return v[i]; } };
The prefix template<class T> specifies that a template is being declared and that a type-name T can be used in the declaration.
In other words, Array is a parameterized type with T as its parameter.
— end example]
[Note 1:
When a member of a class template is defined outside of the class template definition, the member definition is defined as a template definition with the template-head equivalent to that of the class template.
The names of the template parameters used in the definition of the member can differ from the template parameter names used in the class template definition.
The class template name in the member definition is followed by the template argument list of the template-head ([temp.arg]).
[Example 2: template<class T1, class T2> struct A { void f1(); void f2(); }; template<class T2, class T1> void A<T2,T1>::f1() { } // OK template<class T2, class T1> void A<T1,T2>::f2() { } // error
template<class ... Types> struct B { void f3(); void f4(); }; template<class ... Types> void B<Types ...>::f3() { } // OK template<class ... Types> void B<Types>::f4() { } // error
template<typename T> concept C = true; template<typename T> concept D = true; template<C T> struct S { void f(); void g(); void h(); template<D U> struct Inner; }; template<C A> void S<A>::f() { } // OK: template-heads match template<typename T> void S<T>::g() { } // error: no matching declaration for S<T> template<typename T> requires C<T> // ill-formed, no diagnostic required: template-heads are void S<T>::h() { } // functionally equivalent but not equivalent template<C X> template<D Y> struct S<X>::Inner { }; // OK — end example]
— end note]
In a partial specialization, explicit specialization or explicit instantiation of a class template, the class-key shall agree in kind with the original class template declaration ([dcl.type.elab]).

13.7.2.2 Member functions of class templates [temp.mem.func]

A member function of a class template may be defined outside of the class template definition in which it is declared.
[Example 1: template<class T> class Array { T* v; int sz; public: explicit Array(int); T& operator[](int); T& elem(int i) { return v[i]; } };
declares three member functions of a class template.
The subscript function can be defined like this: template<class T> T& Array<T>::operator[](int i) { if (i<0 || sz<=i) error("Array: range error"); return v[i]; }
A constrained member function can be defined out of line: template<typename T> concept C = requires { typename T::type; }; template<typename T> struct S { void f() requires C<T>; void g() requires C<T>; }; template<typename T> void S<T>::f() requires C<T> { } // OK template<typename T> void S<T>::g() { } // error: no matching function in S<T>
— end example]
The template-arguments for a member function of a class template are determined by the template-arguments of the type of the object for which the member function is called.
[Example 2:
The template-argument for Array<T>​::​operator[] will be determined by the Array to which the subscripting operation is applied.
Array<int> v1(20); Array<dcomplex> v2(30); v1[3] = 7; // Array<int>​::​operator[] v2[3] = dcomplex(7,8); // Array<dcomplex>​::​operator[] — end example]

13.7.2.3 Deduction guides [temp.deduct.guide]

Deduction guides are used when a template-name appears as a type specifier for a deduced class type ([dcl.type.class.deduct]).
Deduction guides are not found by name lookup.
Instead, when performing class template argument deduction ([over.match.class.deduct]), all reachable deduction guides declared for the class template are considered.
[Example 1: template<class T, class D = int> struct S { T data; }; template<class U> S(U) -> S<typename U::type>; struct A { using type = short; operator type(); }; S x{A()}; // x is of type S<short, int> — end example]
The same restrictions apply to the parameter-declaration-clause of a deduction guide as in a function declaration ([dcl.fct]).
The simple-template-id shall name a class template specialization.
The template-name shall be the same identifier as the template-name of the simple-template-id.
A deduction-guide shall inhabit the scope to which the corresponding class template belongs and, for a member class template, have the same access.
Two deduction guide declarations for the same class template shall not have equivalent parameter-declaration-clauses if either is reachable from the other.

13.7.2.4 Member classes of class templates [temp.mem.class]

A member class of a class template may be defined outside the class template definition in which it is declared.
[Note 1:
The member class must be defined before its first use that requires an instantiation ([temp.inst]).
For example, template<class T> struct A { class B; }; A<int>::B* b1; // OK: requires A to be defined but not A​::​B template<class T> class A<T>::B { }; A<int>::B b2; // OK: requires A​::​B to be defined
— end note]

13.7.2.5 Static data members of class templates [temp.static]

A definition for a static data member or static data member template may be provided in a namespace scope enclosing the definition of the static member's class template.
[Example 1: template<class T> class X { static T s; }; template<class T> T X<T>::s = 0; struct limits { template<class T> static const T min; // declaration }; template<class T> const T limits::min = { }; // definition — end example]
An explicit specialization of a static data member declared as an array of unknown bound can have a different bound from its definition, if any.
[Example 2: template <class T> struct A { static int i[]; }; template <class T> int A<T>::i[4]; // 4 elements template <> int A<int>::i[] = { 1 }; // OK: 1 element — end example]

13.7.2.6 Enumeration members of class templates [temp.mem.enum]

An enumeration member of a class template may be defined outside the class template definition.
[Example 1: template<class T> struct A { enum E : T; }; A<int> a; template<class T> enum A<T>::E : T { e1, e2 }; A<int>::E e = A<int>::e1; — end example]

13.7.3 Member templates [temp.mem]

A template can be declared within a class or class template; such a template is called a member template.
A member template can be defined within or outside its class definition or class template definition.
A member template of a class template that is defined outside of its class template definition shall be specified with a template-head equivalent to that of the class template followed by a template-head equivalent to that of the member template ([temp.over.link]).
[Example 1: template<class T> struct string { template<class T2> int compare(const T2&); template<class T2> string(const string<T2>& s) { /* ... */ } }; template<class T> template<class T2> int string<T>::compare(const T2& s) { } — end example]
[Example 2: template<typename T> concept C1 = true; template<typename T> concept C2 = sizeof(T) <= 4; template<C1 T> struct S { template<C2 U> void f(U); template<C2 U> void g(U); }; template<C1 T> template<C2 U> void S<T>::f(U) { } // OK template<C1 T> template<typename U> void S<T>::g(U) { } // error: no matching function in S<T> — end example]
A local class of non-closure type shall not have member templates.
Access control rules apply to member template names.
A destructor shall not be a member template.
A non-template member function ([dcl.fct]) with a given name and type and a member function template of the same name, which could be used to generate a specialization of the same type, can both be declared in a class.
When both exist, a use of that name and type refers to the non-template member unless an explicit template argument list is supplied.
[Example 3: template <class T> struct A { void f(int); template <class T2> void f(T2); }; template <> void A<int>::f(int) { } // non-template member function template <> template <> void A<int>::f<>(int) { } // member function template specialization int main() { A<char> ac; ac.f(1); // non-template ac.f('c'); // template ac.f<>(1); // template } — end example]
A member function template shall not be declared virtual.
[Example 4: template <class T> struct AA { template <class C> virtual void g(C); // error virtual void f(); // OK }; — end example]
A specialization of a member function template does not override a virtual function from a base class.
[Example 5: class B { virtual void f(int); }; class D : public B { template <class T> void f(T); // does not override B​::​f(int) void f(int i) { f<>(i); } // overriding function that calls the function template specialization }; — end example]
[Note 1:
A specialization of a conversion function template is referenced in the same way as a non-template conversion function that converts to the same type ([class.conv.fct]).
[Example 6: struct A { template <class T> operator T*(); }; template <class T> A::operator T*() { return 0; } template <> A::operator char*() { return 0; } // specialization template A::operator void*(); // explicit instantiation int main() { A a; int* ip; ip = a.operator int*(); // explicit call to template operator A​::​operator int*() } — end example]
There is no syntax to form a template-id ([temp.names]) by providing an explicit template argument list ([temp.arg.explicit]) for a conversion function template.
— end note]

13.7.4 Variadic templates [temp.variadic]

A template parameter pack is a template parameter that accepts zero or more template arguments.
[Example 1: template<class ... Types> struct Tuple { }; Tuple<> t0; // Types contains no arguments Tuple<int> t1; // Types contains one argument: int Tuple<int, float> t2; // Types contains two arguments: int and float Tuple<0> error; // error: 0 is not a type — end example]
A function parameter pack is a function parameter that accepts zero or more function arguments.
[Example 2: template<class ... Types> void f(Types ... args); f(); // args contains no arguments f(1); // args contains one argument: int f(2, 1.0); // args contains two arguments: int and double — end example]
An init-capture pack is a lambda capture that introduces an init-capture for each of the elements in the pack expansion of its initializer.
[Example 3: template <typename... Args> void foo(Args... args) { [...xs=args]{ bar(xs...); // xs is an init-capture pack }; } foo(); // xs contains zero init-captures foo(1); // xs contains one init-capture — end example]
A pack is a template parameter pack, a function parameter pack, or an init-capture pack.
The number of elements of a template parameter pack or a function parameter pack is the number of arguments provided for the parameter pack.
The number of elements of an init-capture pack is the number of elements in the pack expansion of its initializer.
A pack expansion consists of a pattern and an ellipsis, the instantiation of which produces zero or more instantiations of the pattern in a list (described below).
The form of the pattern depends on the context in which the expansion occurs.
Pack expansions can occur in the following contexts:
[Example 4: template<class ... Types> void f(Types ... rest); template<class ... Types> void g(Types ... rest) { f(&rest ...); // “&rest ...” is a pack expansion; “&rest” is its pattern } — end example]
For the purpose of determining whether a pack satisfies a rule regarding entities other than packs, the pack is considered to be the entity that would result from an instantiation of the pattern in which it appears.
A pack whose name appears within the pattern of a pack expansion is expanded by that pack expansion.
An appearance of the name of a pack is only expanded by the innermost enclosing pack expansion.
The pattern of a pack expansion shall name one or more packs that are not expanded by a nested pack expansion; such packs are called unexpanded packs in the pattern.
All of the packs expanded by a pack expansion shall have the same number of arguments specified.
An appearance of a name of a pack that is not expanded is ill-formed.
[Example 5: template<typename...> struct Tuple {}; template<typename T1, typename T2> struct Pair {}; template<class ... Args1> struct zip { template<class ... Args2> struct with { typedef Tuple<Pair<Args1, Args2> ... > type; }; }; typedef zip<short, int>::with<unsigned short, unsigned>::type T1; // T1 is Tuple<Pair<short, unsigned short>, Pair<int, unsigned>> typedef zip<short>::with<unsigned short, unsigned>::type T2; // error: different number of arguments specified for Args1 and Args2 template<class ... Args> void g(Args ... args) { // OK: Args is expanded by the function parameter pack args f(const_cast<const Args*>(&args)...); // OK: “Args” and “args” are expanded f(5 ...); // error: pattern does not contain any packs f(args); // error: pack “args” is not expanded f(h(args ...) + args ...); // OK: first “args” expanded within h, // second “args” expanded within f } — end example]
The instantiation of a pack expansion considers items , where N is the number of elements in the pack expansion parameters.
Each is generated by instantiating the pattern and replacing each pack expansion parameter with its element.
Such an element, in the context of the instantiation, is interpreted as follows:
  • if the pack is a template parameter pack, the element is an id-expression (for a non-type template parameter pack), a typedef-name (for a type template parameter pack declared without template), or a template-name (for a type template parameter pack declared with template), designating the corresponding type or value template argument;
  • if the pack is a function parameter pack, the element is an id-expression designating the function parameter that resulted from instantiation of the function parameter pack declaration; otherwise
  • if the pack is an init-capture pack, the element is an id-expression designating the variable introduced by the init-capture that resulted from instantiation of the init-capture pack.
When N is zero, the instantiation of a pack expansion does not alter the syntactic interpretation of the enclosing construct, even in cases where omitting the pack expansion entirely would otherwise be ill-formed or would result in an ambiguity in the grammar.
The instantiation of a sizeof... expression ([expr.sizeof]) produces an integral constant with value N.
The instantiation of a fold-expression ([expr.prim.fold]) produces:
  • (( op ) op ) op for a unary left fold,
  • op ( op ( op )) for a unary right fold,
  • (((E op ) op ) op ) op for a binary left fold, and
  • op ( op ( op ( op E))) for a binary right fold.
In each case, op is the fold-operator.
For a binary fold, E is generated by instantiating the cast-expression that did not contain an unexpanded pack.
[Example 6: template<typename ...Args> bool all(Args ...args) { return (... && args); } bool b = all(true, true, true, false);
Within the instantiation of all, the returned expression expands to ((true && true) && true) && false, which evaluates to false.
— end example]
If N is zero for a unary fold, the value of the expression is shown in Table 17; if the operator is not listed in Table 17, the instantiation is ill-formed.
Table 17: Value of folding empty sequences [tab:temp.fold.empty]
Operator
Value when pack is empty
&&
true
||
false
,
void()
The instantiation of any other pack expansion produces a list of elements .
[Note 1:
The variety of list varies with the context: expression-list, base-specifier-list, template-argument-list, etc.
— end note]
When N is zero, the instantiation of the expansion produces an empty list.
[Example 7: template<class... T> struct X : T... { }; template<class... T> void f(T... values) { X<T...> x(values...); } template void f<>(); // OK: X<> has no base classes // x is a variable of type X<> that is value-initialized — end example]

13.7.5 Friends [temp.friend]

A friend of a class or class template can be a function template or class template, a specialization of a function template or class template, or a non-template function or class.
[Example 1: template<class T> class task; template<class T> task<T>* preempt(task<T>*); template<class T> class task { friend void next_time(); friend void process(task<T>*); friend task<T>* preempt<T>(task<T>*); template<class C> friend int func(C); friend class task<int>; template<class P> friend class frd; };
Here, each specialization of the task class template has the function next_­time as a friend; because process does not have explicit template-arguments, each specialization of the task class template has an appropriately typed function process as a friend, and this friend is not a function template specialization; because the friend preempt has an explicit template-argument T, each specialization of the task class template has the appropriate specialization of the function template preempt as a friend; and each specialization of the task class template has all specializations of the function template func as friends.
Similarly, each specialization of the task class template has the class template specialization task<int> as a friend, and has all specializations of the class template frd as friends.
— end example]
Friend classes, class templates, functions, or function templates can be declared within a class template.
When a template is instantiated, its friend declarations are found by name lookup as if the specialization had been explicitly declared at its point of instantiation.
[Note 1:
They can introduce entities that belong to an enclosing namespace scope ([dcl.meaning]), in which case they are attached to the same module as the class template ([module.unit]).
— end note]
A friend template may be declared within a class or class template.
A friend function template may be defined within a class or class template, but a friend class template may not be defined in a class or class template.
In these cases, all specializations of the friend class or friend function template are friends of the class or class template granting friendship.
[Example 2: class A { template<class T> friend class B; // OK template<class T> friend void f(T) { /* ... */ } // OK }; — end example]
A template friend declaration specifies that all specializations of that template, whether they are implicitly instantiated ([temp.inst]), partially specialized ([temp.spec.partial]) or explicitly specialized ([temp.expl.spec]), are friends of the class containing the template friend declaration.
[Example 3: class X { template<class T> friend struct A; class Y { }; }; template<class T> struct A { X::Y ab; }; // OK template<class T> struct A<T*> { X::Y ab; }; // OK — end example]
A template friend declaration may declare a member of a dependent type to be a friend.
The friend declaration shall declare a function or specify a type with an elaborated-type-specifier, in either case with a nested-name-specifier ending with a simple-template-id, C, whose template-name names a class template.
The template parameters of the template friend declaration shall be deducible from C ([temp.deduct.type]).
In this case, a member of a specialization S of the class template is a friend of the class granting friendship if deduction of the template parameters of C from S succeeds, and substituting the deduced template arguments into the friend declaration produces a declaration that corresponds to the member of the specialization.
[Example 4: template<class T> struct A { struct B { }; void f(); struct D { void g(); }; T h(); template<T U> T i(); }; template<> struct A<int> { struct B { }; int f(); struct D { void g(); }; template<int U> int i(); }; template<> struct A<float*> { int *h(); }; class C { template<class T> friend struct A<T>::B; // grants friendship to A<int>​::​B even though // it is not a specialization of A<T>​::​B template<class T> friend void A<T>::f(); // does not grant friendship to A<int>​::​f() // because its return type does not match template<class T> friend void A<T>::D::g(); // error: A<T>​::​D does not end with a simple-template-id template<class T> friend int *A<T*>::h(); // grants friendship to A<int*>​::​h() and A<float*>​::​h() template<class T> template<T U> // grants friendship to instantiations of A<T>​::​i() and friend T A<T>::i(); // to A<int>​::​i(), and thereby to all specializations }; // of those function templates — end example]
A friend template shall not be declared in a local class.
Friend declarations shall not declare partial specializations.
[Example 5: template<class T> class A { }; class X { template<class T> friend class A<T*>; // error }; — end example]
When a friend declaration refers to a specialization of a function template, the function parameter declarations shall not include default arguments, nor shall the inline, constexpr, or consteval specifiers be used in such a declaration.
A non-template friend declaration with a requires-clause shall be a definition.
A friend function template with a constraint that depends on a template parameter from an enclosing template shall be a definition.
Such a constrained friend function or function template declaration does not declare the same function or function template as a declaration in any other scope.

13.7.6 Partial specialization [temp.spec.partial]

13.7.6.1 General [temp.spec.partial.general]

A partial specialization of a template provides an alternative definition of the template that is used instead of the primary definition when the arguments in a specialization match those given in the partial specialization ([temp.spec.partial.match]).
A declaration of the primary template shall precede any partial specialization of that template.
A partial specialization shall be reachable from any use of a template specialization that would make use of the partial specialization as the result of an implicit or explicit instantiation; no diagnostic is required.
Two partial specialization declarations declare the same entity if they are partial specializations of the same template and have equivalent template-heads and template argument lists ([temp.over.link]).
Each partial specialization is a distinct template.
[Example 1: template<class T1, class T2, int I> class A { }; template<class T, int I> class A<T, T*, I> { }; template<class T1, class T2, int I> class A<T1*, T2, I> { }; template<class T> class A<int, T*, 5> { }; template<class T1, class T2, int I> class A<T1, T2*, I> { };
The first declaration declares the primary (unspecialized) class template.
The second and subsequent declarations declare partial specializations of the primary template.
— end example]
A partial specialization may be constrained ([temp.constr]).
[Example 2: template<typename T> concept C = true; template<typename T> struct X { }; template<typename T> struct X<T*> { }; // #1 template<C T> struct X<T> { }; // #2
Both partial specializations are more specialized than the primary template.
#1 is more specialized because the deduction of its template arguments from the template argument list of the class template specialization succeeds, while the reverse does not.
#2 is more specialized because the template arguments are equivalent, but the partial specialization is more constrained ([temp.constr.order]).
— end example]
The template argument list of a partial specialization is the template-argument-list following the name of the template.
A partial specialization may be declared in any scope in which the corresponding primary template may be defined ([dcl.meaning], [class.mem], [temp.mem]).
[Example 3: template<class T> struct A { struct C { template<class T2> struct B { }; template<class T2> struct B<T2**> { }; // partial specialization #1 }; }; // partial specialization of A<T>​::​C​::​B<T2> template<class T> template<class T2> struct A<T>::C::B<T2*> { }; // #2 A<short>::C::B<int*> absip; // uses partial specialization #2 — end example]
Partial specialization declarations do not introduce a name.
Instead, when the primary template name is used, any reachable partial specializations of the primary template are also considered.
[Note 1:
One consequence is that a using-declaration which refers to a class template does not restrict the set of partial specializations that are found through the using-declaration.
— end note]
[Example 4: namespace N { template<class T1, class T2> class A { }; // primary template } using N::A; // refers to the primary template namespace N { template<class T> class A<T, T*> { }; // partial specialization } A<int,int*> a; // uses the partial specialization, which is found through the using-declaration // which refers to the primary template — end example]
A non-type argument is non-specialized if it is the name of a non-type parameter.
All other non-type arguments are specialized.
Within the argument list of a partial specialization, the following restrictions apply:
  • The type of a template parameter corresponding to a specialized non-type argument shall not be dependent on a parameter of the partial specialization.
    [Example 5: template <class T, T t> struct C {}; template <class T> struct C<T, 1>; // error template< int X, int (*array_ptr)[X] > class A {}; int array[5]; template< int X > class A<X,&array> { }; // error — end example]
  • The partial specialization shall be more specialized than the primary template ([temp.spec.partial.order]).
  • The template parameter list of a partial specialization shall not contain default template argument values.127
  • An argument shall not contain an unexpanded pack.
    If an argument is a pack expansion ([temp.variadic]), it shall be the last argument in the template argument list.
The usual access checking rules do not apply to non-dependent names used to specify template arguments of the simple-template-id of the partial specialization.
[Note 2:
The template arguments can be private types or objects that would normally not be accessible.
Dependent names cannot be checked when declaring the partial specialization, but will be checked when substituting into the partial specialization.
— end note]
127)127)
There is no context in which they would be used.

13.7.6.2 Matching of partial specializations [temp.spec.partial.match]

When a template is used in a context that requires an instantiation of the template, it is necessary to determine whether the instantiation is to be generated using the primary template or one of the partial specializations.
This is done by matching the template arguments of the template specialization with the template argument lists of the partial specializations.
  • If exactly one matching partial specialization is found, the instantiation is generated from that partial specialization.
  • If more than one matching partial specialization is found, the partial order rules ([temp.spec.partial.order]) are used to determine whether one of the partial specializations is more specialized than the others.
    If such a partial specialization exists, the instantiation is generated from that partial specialization; otherwise, the use of the template is ambiguous and the program is ill-formed.
  • If no matches are found, the instantiation is generated from the primary template.
A partial specialization matches a given actual template argument list if the template arguments of the partial specialization can be deduced from the actual template argument list, and the deduced template arguments satisfy the associated constraints of the partial specialization, if any.
[Example 1: template<class T1, class T2, int I> class A { }; // #1 template<class T, int I> class A<T, T*, I> { }; // #2 template<class T1, class T2, int I> class A<T1*, T2, I> { }; // #3 template<class T> class A<int, T*, 5> { }; // #4 template<class T1, class T2, int I> class A<T1, T2*, I> { }; // #5 A<int, int, 1> a1; // uses #1 A<int, int*, 1> a2; // uses #2, T is int, I is 1 A<int, char*, 5> a3; // uses #4, T is char A<int, char*, 1> a4; // uses #5, T1 is int, T2 is char, I is 1 A<int*, int*, 2> a5; // ambiguous: matches #3 and #5 — end example]
[Example 2: template<typename T> concept C = requires (T t) { t.f(); }; template<typename T> struct S { }; // #1 template<C T> struct S<T> { }; // #2 struct Arg { void f(); }; S<int> s1; // uses #1; the constraints of #2 are not satisfied S<Arg> s2; // uses #2; both constraints are satisfied but #2 is more specialized — end example]
If the template arguments of a partial specialization cannot be deduced because of the structure of its template-parameter-list and the template-id, the program is ill-formed.
[Example 3: template <int I, int J> struct A {}; template <int I> struct A<I+5, I*2> {}; // error template <int I> struct A<I, I> {}; // OK template <int I, int J, int K> struct B {}; template <int I> struct B<I, I*2, 2> {}; // OK — end example]
In a name that refers to a specialization of a class or variable template (e.g., A<int, int, 1>), the argument list shall match the template parameter list of the primary template.
The template arguments of a partial specialization are deduced from the arguments of the primary template.

13.7.6.3 Partial ordering of partial specializations [temp.spec.partial.order]

For two partial specializations, the first is more specialized than the second if, given the following rewrite to two function templates, the first function template is more specialized than the second according to the ordering rules for function templates:
  • Each of the two function templates has the same template parameters and associated constraints as the corresponding partial specialization.
  • Each function template has a single function parameter whose type is a class template specialization where the template arguments are the corresponding template parameters from the function template for each template argument in the template-argument-list of the simple-template-id of the partial specialization.
[Example 1: template<int I, int J, class T> class X { }; template<int I, int J> class X<I, J, int> { }; // #1 template<int I> class X<I, I, int> { }; // #2 template<int I0, int J0> void f(X<I0, J0, int>); // A template<int I0> void f(X<I0, I0, int>); // B template <auto v> class Y { }; template <auto* p> class Y<p> { }; // #3 template <auto** pp> class Y<pp> { }; // #4 template <auto* p0> void g(Y<p0>); // C template <auto** pp0> void g(Y<pp0>); // D
According to the ordering rules for function templates, the function template B is more specialized than the function template A and the function template D is more specialized than the function template C.
Therefore, the partial specialization #2 is more specialized than the partial specialization #1 and the partial specialization #4 is more specialized than the partial specialization #3.
— end example]
[Example 2: template<typename T> concept C = requires (T t) { t.f(); }; template<typename T> concept D = C<T> && requires (T t) { t.f(); }; template<typename T> class S { }; template<C T> class S<T> { }; // #1 template<D T> class S<T> { }; // #2 template<C T> void f(S<T>); // A template<D T> void f(S<T>); // B
The partial specialization #2 is more specialized than #1 because B is more specialized than A.
— end example]

13.7.6.4 Members of class template partial specializations [temp.spec.partial.member]

The members of the class template partial specialization are unrelated to the members of the primary template.
Class template partial specialization members that are used in a way that requires a definition shall be defined; the definitions of members of the primary template are never used as definitions for members of a class template partial specialization.
An explicit specialization of a member of a class template partial specialization is declared in the same way as an explicit specialization of a member of the primary template.
[Example 1: // primary class template template<class T, int I> struct A { void f(); }; // member of primary class template template<class T, int I> void A<T,I>::f() { } // class template partial specialization template<class T> struct A<T,2> { void f(); void g(); void h(); }; // member of class template partial specialization template<class T> void A<T,2>::g() { } // explicit specialization template<> void A<char,2>::h() { } int main() { A<char,0> a0; A<char,2> a2; a0.f(); // OK, uses definition of primary template's member a2.g(); // OK, uses definition of partial specialization's member a2.h(); // OK, uses definition of explicit specialization's member a2.f(); // error: no definition of f for A<T,2>; the primary template is not used here } — end example]
If a member template of a class template is partially specialized, the member template partial specializations are member templates of the enclosing class template; if the enclosing class template is instantiated ([temp.inst], [temp.explicit]), a declaration for every member template partial specialization is also instantiated as part of creating the members of the class template specialization.
If the primary member template is explicitly specialized for a given (implicit) specialization of the enclosing class template, the partial specializations of the member template are ignored for this specialization of the enclosing class template.
If a partial specialization of the member template is explicitly specialized for a given (implicit) specialization of the enclosing class template, the primary member template and its other partial specializations are still considered for this specialization of the enclosing class template.
[Example 2: template<class T> struct A { template<class T2> struct B {}; // #1 template<class T2> struct B<T2*> {}; // #2 }; template<> template<class T2> struct A<short>::B {}; // #3 A<char>::B<int*> abcip; // uses #2 A<short>::B<int*> absip; // uses #3 A<char>::B<int> abci; // uses #1 — end example]

13.7.7 Function templates [temp.fct]

13.7.7.1 General [temp.fct.general]

A function template defines an unbounded set of related functions.
[Example 1:
A family of sort functions can be declared like this: template<class T> class Array { }; template<class T> void sort(Array<T>&);
— end example]
[Note 1:
A function template can have the same name as other function templates and non-template functions ([dcl.fct]) in the same scope.
— end note]
A non-template function is not related to a function template (i.e., it is never considered to be a specialization), even if it has the same name and type as a potentially generated function template specialization.128
128)128)
That is, declarations of non-template functions do not merely guide overload resolution of function template specializations with the same name.
If such a non-template function is odr-used ([basic.def.odr]) in a program, it must be defined; it will not be implicitly instantiated using the function template definition.

13.7.7.3 Partial ordering of function templates [temp.func.order]

If multiple function templates share a name, the use of that name can be ambiguous because template argument deduction ([temp.deduct]) may identify a specialization for more than one function template.
Partial ordering of overloaded function template declarations is used in the following contexts to select the function template to which a function template specialization refers:
Partial ordering selects which of two function templates is more specialized than the other by transforming each template in turn (see next paragraph) and performing template argument deduction using the function type.
The deduction process determines whether one of the templates is more specialized than the other.
If so, the more specialized template is the one chosen by the partial ordering process.
If both deductions succeed, the partial ordering selects the more constrained template (if one exists) as determined below.
To produce the transformed template, for each type, non-type, or template template parameter (including template parameter packs thereof) synthesize a unique type, value, or class template respectively and substitute it for each occurrence of that parameter in the function type of the template.
[Note 1:
The type replacing the placeholder in the type of the value synthesized for a non-type template parameter is also a unique synthesized type.
— end note]
Each function template M that is a member function is considered to have a new first parameter of type X(M), described below, inserted in its function parameter list.
If exactly one of the function templates was considered by overload resolution via a rewritten candidate ([over.match.oper]) with a reversed order of parameters, then the order of the function parameters in its transformed template is reversed.
For a function template M with cv-qualifiers cv that is a member of a class A:
  • The type X(M) is “rvalue reference to cv A” if the optional ref-qualifier of M is && or if M has no ref-qualifier and the positionally-corresponding parameter of the other transformed template has rvalue reference type; if this determination depends recursively upon whether X(M) is an rvalue reference type, it is not considered to have rvalue reference type.
  • Otherwise, X(M) is “lvalue reference to cv A.
[Note 2:
This allows a non-static member to be ordered with respect to a non-member function and for the results to be equivalent to the ordering of two equivalent non-members.
— end note]
[Example 1: struct A { }; template<class T> struct B { template<class R> int operator*(R&); // #1 }; template<class T, class R> int operator*(T&, R&); // #2 // The declaration of B​::​operator* is transformed into the equivalent of // template<class R> int operator*(B<A>&, R&);      // #1a int main() { A a; B<A> b; b * a; // calls #1 } — end example]
Using the transformed function template's function type, perform type deduction against the other template as described in [temp.deduct.partial].
[Example 2: template<class T> struct A { A(); }; template<class T> void f(T); template<class T> void f(T*); template<class T> void f(const T*); template<class T> void g(T); template<class T> void g(T&); template<class T> void h(const T&); template<class T> void h(A<T>&); void m() { const int* p; f(p); // f(const T*) is more specialized than f(T) or f(T*) float x; g(x); // ambiguous: g(T) or g(T&) A<int> z; h(z); // overload resolution selects h(A<T>&) const A<int> z2; h(z2); // h(const T&) is called because h(A<T>&) is not callable } — end example]
[Note 3:
Since, in a call context, such type deduction considers only parameters for which there are explicit call arguments, some parameters are ignored (namely, function parameter packs, parameters with default arguments, and ellipsis parameters).
[Example 3: template<class T> void f(T); // #1 template<class T> void f(T*, int=1); // #2 template<class T> void g(T); // #3 template<class T> void g(T*, ...); // #4 int main() { int* ip; f(ip); // calls #2 g(ip); // calls #4 } — end example]
[Example 4: template<class T, class U> struct A { }; template<class T, class U> void f(U, A<U, T>* p = 0); // #1 template< class U> void f(U, A<U, U>* p = 0); // #2 template<class T > void g(T, T = T()); // #3 template<class T, class... U> void g(T, U ...); // #4 void h() { f<int>(42, (A<int, int>*)0); // calls #2 f<int>(42); // error: ambiguous g(42); // error: ambiguous } — end example]
[Example 5: template<class T, class... U> void f(T, U...); // #1 template<class T > void f(T); // #2 template<class T, class... U> void g(T*, U...); // #3 template<class T > void g(T); // #4 void h(int i) { f(&i); // OK: calls #2 g(&i); // OK: calls #3 } — end example]
— end note]
If deduction against the other template succeeds for both transformed templates, constraints can be considered as follows:
  • If their template-parameter-lists (possibly including template-parameters invented for an abbreviated function template ([dcl.fct])) or function parameter lists differ in length, neither template is more specialized than the other.
  • Otherwise:
    • If exactly one of the templates was considered by overload resolution via a rewritten candidate with reversed order of parameters:
      • If, for either template, some of the template parameters are not deducible from their function parameters, neither template is more specialized than the other.
      • If there is either no reordering or more than one reordering of the associated template-parameter-list such that neither template is more specialized than the other.
    • Otherwise, if the corresponding template-parameters of the template-parameter-lists are not equivalent ([temp.over.link]) or if the function parameters that positionally correspond between the two templates are not of the same type, neither template is more specialized than the other.
  • Otherwise, if the context in which the partial ordering is done is that of a call to a conversion function and the return types of the templates are not the same, then neither template is more specialized than the other.
  • Otherwise, if one template is more constrained than the other ([temp.constr.order]), the more constrained template is more specialized than the other.
  • Otherwise, neither template is more specialized than the other.
[Example 6: template <typename> constexpr bool True = true; template <typename T> concept C = True<T>; void f(C auto &, auto &) = delete; template <C Q> void f(Q &, C auto &); void g(struct A *ap, struct B *bp) { f(*ap, *bp); // OK: Can use different methods to produce template parameters } template <typename T, typename U> struct X {}; template <typename T, C U, typename V> bool operator==(X<T, U>, V) = delete; template <C T, C U, C V> bool operator==(T, X<U, V>); void h() { X<void *, int>{} == 0; // OK: Correspondence of [T, U, V] and [U, V, T] } — end example]

13.7.8 Alias templates [temp.alias]

An alias template is a name for a family of types.
The name of the alias template is a template-name.
When a template-id refers to the specialization of an alias template, it is equivalent to the associated type obtained by substitution of its template-arguments for the template-parameters in the defining-type-id of the alias template.
[Note 1:
An alias template name is never deduced.
— end note]
[Example 1: template<class T> struct Alloc { /* ... */ }; template<class T> using Vec = vector<T, Alloc<T>>; Vec<int> v; // same as vector<int, Alloc<int>> v; template<class T> void process(Vec<T>& v) { /* ... */ } template<class T> void process(vector<T, Alloc<T>>& w) { /* ... */ } // error: redefinition template<template<class> class TT> void f(TT<int>); f(v); // error: Vec not deduced template<template<class,class> class TT> void g(TT<int, Alloc<int>>); g(v); // OK: TT = vector — end example]
However, if the template-id is dependent, subsequent template argument substitution still applies to the template-id.
[Example 2: template<typename...> using void_t = void; template<typename T> void_t<typename T::foo> f(); f<int>(); // error: int does not have a nested type foo — end example]
The defining-type-id in an alias template declaration shall not refer to the alias template being declared.
The type produced by an alias template specialization shall not directly or indirectly make use of that specialization.
[Example 3: template <class T> struct A; template <class T> using B = typename A<T>::U; template <class T> struct A { typedef B<T> U; }; B<short> b; // error: instantiation of B<short> uses own type via A<short>​::​U — end example]
The type of a lambda-expression appearing in an alias template declaration is different between instantiations of that template, even when the lambda-expression is not dependent.
[Example 4: template <class T> using A = decltype([] { }); // A<int> and A<char> refer to different closure types — end example]

13.7.9 Concept definitions [temp.concept]

A concept is a template that defines constraints on its template arguments.
A concept-definition declares a concept.
Its identifier becomes a concept-name referring to that concept within its scope.
[Example 1: template<typename T> concept C = requires(T x) { { x == x } -> std::convertible_­to<bool>; }; template<typename T> requires C<T> // C constrains f1(T) in constraint-expression T f1(T x) { return x; } template<C T> // C, as a type-constraint, constrains f2(T) T f2(T x) { return x; } — end example]
A concept-definition shall inhabit a namespace scope ([basic.scope.namespace]).
A concept shall not have associated constraints.
A concept is not instantiated ([temp.spec]).
[Note 1:
A concept-id ([temp.names]) is evaluated as an expression.
A concept cannot be explicitly instantiated ([temp.explicit]), explicitly specialized ([temp.expl.spec]), or partially specialized ([temp.spec.partial]).
— end note]
The constraint-expression of a concept-definition is an unevaluated operand ([expr.context]).
The first declared template parameter of a concept definition is its prototype parameter.
A type concept is a concept whose prototype parameter is a type template-parameter.

13.8 Name resolution [temp.res]

13.8.1 General [temp.res.general]

A name that appears in a declaration D of a template T is looked up from where it appears in an unspecified declaration of T that is or is reachable from D and from which no other declaration of T that contains the usage of the name is reachable.
If the name is dependent (as specified in [temp.dep]), it is looked up for each specialization (after substitution) because the lookup depends on a template parameter.
[Note 1:
Some dependent names are also looked up during parsing to determine that they are dependent or to interpret following < tokens.
Uses of other names might be type-dependent or value-dependent ([temp.dep.expr], [temp.dep.constexpr]).
A using-declarator is never dependent in a specialization and is therefore replaced during lookup for that specialization ([basic.lookup]).
— end note]
[Example 1: struct A { operator int(); }; template<class B, class T> struct D : B { T get() { return operator T(); } // conversion-function-id is dependent }; int f(D<A, int> d) { return d.get(); } // OK: lookup finds A::operator int — end example]
[Example 2: void f(char); template<class T> void g(T t) { f(1); // f(char) f(T(1)); // dependent f(t); // dependent dd++; // not dependent; error: declaration for dd not found } enum E { e }; void f(E); double dd; void h() { g(e); // will cause one call of f(char) followed by two calls of f(E) g('a'); // will cause three calls of f(char) } — end example]
[Example 3: struct A { struct B { /* ... */ }; int a; int Y; }; int a; template<class T> struct Y : T { struct B { /* ... */ }; B b; // The B defined in Y void f(int i) { a = i; } // ​::​a Y* p; // Y<T> }; Y<A> ya;
The members A​::​B, A​::​a, and A​::​Y of the template argument A do not affect the binding of names in Y<A>.
— end example]
If the validity or meaning of the program would be changed by considering a default argument or default template argument introduced in a declaration that is reachable from the point of instantiation of a specialization ([temp.point]) but is not found by lookup for the specialization, the program is ill-formed, no diagnostic required.
The component names of a typename-specifier are its identifier (if any) and those of its nested-name-specifier and simple-template-id (if any).
A typename-specifier denotes the type or class template denoted by the simple-type-specifier ([dcl.type.simple]) formed by omitting the keyword typename.
[Note 2:
The usual qualified name lookup ([basic.lookup.qual]) applies even in the presence of typename.
— end note]
[Example 4: struct A { struct X { }; int X; }; struct B { struct X { }; }; template<class T> void f(T t) { typename T::X x; } void foo() { A a; B b; f(b); // OK: T​::​X refers to B​::​X f(a); // error: T​::​X refers to the data member A​::​X not the struct A​::​X } — end example]
A qualified or unqualified name is said to be in a type-only context if it is the terminal name of
[Example 5: template<class T> T::R f(); // OK, return type of a function declaration at global scope template<class T> void f(T::R); // ill-formed, no diagnostic required: attempt to declare // a void variable template template<class T> struct S { using Ptr = PtrTraits<T>::Ptr; // OK, in a defining-type-id T::R f(T::P p) { // OK, class scope return static_cast<T::R>(p); // OK, type-id of a static_­cast } auto g() -> S<T*>::Ptr; // OK, trailing-return-type }; template<typename T> void f() { void (*pf)(T::X); // variable pf of type void* initialized with T​::​X void g(T::X); // error: T​::​X at block scope does not denote a type // (attempt to declare a void variable) } — end example]
A qualified-id whose terminal name is dependent and that is in a type-only context is considered to denote a type.
A name that refers to a using-declarator whose terminal name is dependent is interpreted as a typedef-name if the using-declarator uses the keyword typename.
[Example 6: template <class T> void f(int i) { T::x * i; // expression, not the declaration of a variable i } struct Foo { typedef int x; }; struct Bar { static int const x = 5; }; int main() { f<Bar>(1); // OK f<Foo>(1); // error: Foo​::​x is a type } — end example]
The validity of a template may be checked prior to any instantiation.
[Note 3:
Knowing which names are type names allows the syntax of every template to be checked in this way.
— end note]
The program is ill-formed, no diagnostic required, if:
  • no valid specialization can be generated for a template or a substatement of a constexpr if statement within a template and the template is not instantiated, or
  • any constraint-expression in the program, introduced or otherwise, has (in its normal form) an atomic constraint A where no satisfaction check of A could be well-formed and no satisfaction check of A is performed, or
  • every valid specialization of a variadic template requires an empty template parameter pack, or
  • a hypothetical instantiation of a template immediately following its definition would be ill-formed due to a construct that does not depend on a template parameter, or
  • the interpretation of such a construct in the hypothetical instantiation is different from the interpretation of the corresponding construct in any actual instantiation of the template.
    [Note 4:
    This can happen in situations including the following:
    • a type used in a non-dependent name is incomplete at the point at which a template is defined but is complete at the point at which an instantiation is performed, or
    • lookup for a name in the template definition found a using-declaration, but the lookup in the corresponding scope in the instantiation does not find any declarations because the using-declaration was a pack expansion and the corresponding pack is empty, or
    • an instantiation uses a default argument or default template argument that had not been defined at the point at which the template was defined, or
    • constant expression evaluation within the template instantiation uses
      • the value of a const object of integral or unscoped enumeration type or
      • the value of a constexpr object or
      • the value of a reference or
      • the definition of a constexpr function,
      and that entity was not defined when the template was defined, or
    • a class template specialization or variable template specialization that is specified by a non-dependent simple-template-id is used by the template, and either it is instantiated from a partial specialization that was not defined when the template was defined or it names an explicit specialization that was not declared when the template was defined.
    — end note]
Otherwise, no diagnostic shall be issued for a template for which a valid specialization can be generated.
[Note 5:
If a template is instantiated, errors will be diagnosed according to the other rules in this document.
Exactly when these errors are diagnosed is a quality of implementation issue.
— end note]
[Example 7: int j; template<class T> class X { void f(T t, int i, char* p) { t = i; // diagnosed if X​::​f is instantiated, and the assignment to t is an error p = i; // may be diagnosed even if X​::​f is not instantiated p = j; // may be diagnosed even if X​::​f is not instantiated X<T>::g(t); // OK X<T>::h(); // may be diagnosed even if X​::​f is not instantiated } void g(T t) { +; // may be diagnosed even if X​::​g is not instantiated } }; template<class... T> struct A { void operator++(int, T... t); // error: too many parameters }; template<class... T> union X : T... { }; // error: union with base class template<class... T> struct A : T..., T... { }; // error: duplicate base class — end example]
[Note 6:
For purposes of name lookup, default arguments and noexcept-specifiers of function templates and default arguments and noexcept-specifiers of member functions of class templates are considered definitions ([temp.decls]).
— end note]
129)129)
This includes friend function declarations.

13.8.2 Locally declared names [temp.local]

Like normal (non-template) classes, class templates have an injected-class-name ([class.pre]).
The injected-class-name can be used as a template-name or a type-name.
When it is used with a template-argument-list, as a template-argument for a template template-parameter, or as the final identifier in the elaborated-type-specifier of a friend class template declaration, it is a template-name that refers to the class template itself.
Otherwise, it is a type-name equivalent to the template-name followed by the template-parameters of the class template enclosed in <>.
When the inject-class-name of a class template specialization or partial specialization is used as a type-name, it is equivalent to the template-name followed by the template-arguments of the class template specialization or partial specialization enclosed in <>.
[Example 1: template<template<class> class T> class A { }; template<class T> class Y; template<> class Y<int> { Y* p; // meaning Y<int> Y<char>* q; // meaning Y<char> A<Y>* a; // meaning A<​::​Y> class B { template<class> friend class Y; // meaning ​::​Y }; }; — end example]
The injected-class-name of a class template or class template specialization can be used as either a template-name or a type-name wherever it is named.
[Example 2: template <class T> struct Base { Base* p; }; template <class T> struct Derived: public Base<T> { typename Derived::Base* p; // meaning Derived​::​Base<T> }; template<class T, template<class> class U = T::Base> struct Third { }; Third<Derived<int> > t; // OK: default argument uses injected-class-name as a template — end example]
A lookup that finds an injected-class-name ([class.member.lookup]) can result in an ambiguity in certain cases (for example, if it is found in more than one base class).
If all of the injected-class-names that are found refer to specializations of the same class template, and if the name is used as a template-name, the reference refers to the class template itself and not a specialization thereof, and is not ambiguous.
[Example 3: template <class T> struct Base { }; template <class T> struct Derived: Base<int>, Base<char> { typename Derived::Base b; // error: ambiguous typename Derived::Base<double> d; // OK }; — end example]
When the normal name of the template (i.e., the name from the enclosing scope, not the injected-class-name) is used, it always refers to the class template itself and not a specialization of the template.
[Example 4: template<class T> class X { X* p; // meaning X<T> X<T>* p2; X<int>* p3; ::X* p4; // error: missing template argument list // ​::​X does not refer to the injected-class-name }; — end example]
The name of a template-parameter shall not be bound to any following declaration contained by the scope to which the template-parameter belongs.
[Example 5: template<class T, int i> class Y { int T; // error: template-parameter hidden void f() { char T; // error: template-parameter hidden } friend void T(); // OK: no name bound }; template<class X> class X; // error: hidden by template-parameter — end example]
Unqualified name lookup considers the template parameter scope of a template-declaration immediately after the outermost scope associated with the template declared (even if its parent scope does not contain the template-parameter-list).
[Note 1:
The scope of a class template, including its non-dependent base classes ([temp.dep.type], [class.member.lookup]), is searched before its template parameter scope.
— end note]
[Example 6: struct B { }; namespace N { typedef void V; template<class T> struct A : B { typedef void C; void f(); template<class U> void g(U); }; } template<class V> void N::A<V>::f() { // N​::​V not considered here V v; // V is still the template parameter, not N​::​V } template<class B> template<class C> void N::A<B>::g(C) { B b; // B is the base class, not the template parameter C c; // C is the template parameter, not A's C } — end example]

13.8.3 Dependent names [temp.dep]

13.8.3.1 General [temp.dep.general]

Inside a template, some constructs have semantics which may differ from one instantiation to another.
Such a construct depends on the template parameters.
In particular, types and expressions may depend on the type and/or value of template parameters (as determined by the template arguments) and this determines the context for name lookup for certain names.
An expression may be type-dependent (that is, its type may depend on a template parameter) or value-dependent (that is, its value when evaluated as a constant expression ([expr.const]) may depend on a template parameter) as described below.
A dependent call is an expression, possibly formed as a non-member candidate for an operator ([over.match.oper]), of the form: where the postfix-expression is an unqualified-id and
The component name of an unqualified-id ([expr.prim.id.unqual]) is dependent if
[Note 1:
Such names are looked up only at the point of the template instantiation ([temp.point]) in both the context of the template definition and the context of the point of instantiation ([temp.dep.candidate]).
— end note]
[Example 1: template<class T> struct X : B<T> { typename T::A* pa; void f(B<T>* pb) { static int i = B<T>::i; pb->j++; } };
The base class name B<T>, the type name T​::​A, the names B<T>​::​i and pb->j explicitly depend on the template-parameter.
— end example]

13.8.3.2 Dependent types [temp.dep.type]

A name or template-id refers to the current instantiation if it is
  • in the definition of a class template, a nested class of a class template, a member of a class template, or a member of a nested class of a class template, the injected-class-name of the class template or nested class,
  • in the definition of a primary class template or a member of a primary class template, the name of the class template followed by the template argument list of its template-head ([temp.arg]) enclosed in <> (or an equivalent template alias specialization),
  • in the definition of a nested class of a class template, the name of the nested class referenced as a member of the current instantiation, or
  • in the definition of a class template partial specialization or a member of a class template partial specialization, the name of the class template followed by a template argument list equivalent to that of the partial specialization ([temp.spec.partial]) enclosed in <> (or an equivalent template alias specialization).
A template argument that is equivalent to a template parameter can be used in place of that template parameter in a reference to the current instantiation.
For a template type-parameter, a template argument is equivalent to a template parameter if it denotes the same type.
For a non-type template parameter, a template argument is equivalent to a template parameter if it is an identifier that names a variable that is equivalent to the template parameter.
A variable is equivalent to a template parameter if
  • it has the same type as the template parameter (ignoring cv-qualification) and
  • its initializer consists of a single identifier that names the template parameter or, recursively, such a variable.
[Note 1:
Using a parenthesized variable name breaks the equivalence.
— end note]
[Example 1: template <class T> class A { A* p1; // A is the current instantiation A<T>* p2; // A<T> is the current instantiation A<T*> p3; // A<T*> is not the current instantiation ::A<T>* p4; // ​::​A<T> is the current instantiation class B { B* p1; // B is the current instantiation A<T>::B* p2; // A<T>​::​B is the current instantiation typename A<T*>::B* p3; // A<T*>​::​B is not the current instantiation }; }; template <class T> class A<T*> { A<T*>* p1; // A<T*> is the current instantiation A<T>* p2; // A<T> is not the current instantiation }; template <class T1, class T2, int I> struct B { B<T1, T2, I>* b1; // refers to the current instantiation B<T2, T1, I>* b2; // not the current instantiation typedef T1 my_T1; static const int my_I = I; static const int my_I2 = I+0; static const int my_I3 = my_I; static const long my_I4 = I; static const int my_I5 = (I); B<my_T1, T2, my_I>* b3; // refers to the current instantiation B<my_T1, T2, my_I2>* b4; // not the current instantiation B<my_T1, T2, my_I3>* b5; // refers to the current instantiation B<my_T1, T2, my_I4>* b6; // not the current instantiation B<my_T1, T2, my_I5>* b7; // not the current instantiation }; — end example]
A dependent base class is a base class that is a dependent type and is not the current instantiation.
[Note 2:
A base class can be the current instantiation in the case of a nested class naming an enclosing class as a base.
[Example 2: template<class T> struct A { typedef int M; struct B { typedef void M; struct C; }; }; template<class T> struct A<T>::B::C : A<T> { M m; // OK, A<T>​::​M }; — end example]
— end note]
A qualified ([basic.lookup.qual]) or unqualified name is a member of the current instantiation if
  • its lookup context, if it is a qualified name, is the current instantiation, and
  • lookup for it finds any member of a class that is the current instantiation
[Example 3: template <class T> class A { static const int i = 5; int n1[i]; // i refers to a member of the current instantiation int n2[A::i]; // A​::​i refers to a member of the current instantiation int n3[A<T>::i]; // A<T>​::​i refers to a member of the current instantiation int f(); }; template <class T> int A<T>::f() { return i; // i refers to a member of the current instantiation } — end example]
A qualified or unqualified name names a dependent member of the current instantiation if it is a member of the current instantiation that, when looked up, refers to at least one member declaration (including a using-declarator whose terminal name is dependent) of a class that is the current instantiation.
A qualified name ([basic.lookup.qual]) is dependent if
[Example 4: struct A { using B = int; A f(); }; struct C : A {}; template<class T> void g(T t) { decltype(t.A::f())::B i; // error: typename needed to interpret B as a type } template void g(C); // …even though A is ​::​A here — end example]
If, for a given set of template arguments, a specialization of a template is instantiated that refers to a member of the current instantiation with a qualified name, the name is looked up in the template instantiation context.
If the result of this lookup differs from the result of name lookup in the template definition context, name lookup is ambiguous.
[Example 5: struct A { int m; }; struct B { int m; }; template<typename T> struct C : A, T { int f() { return this->m; } // finds A​::​m in the template definition context int g() { return m; } // finds A​::​m in the template definition context }; template int C<B>::f(); // error: finds both A​::​m and B​::​m template int C<B>::g(); // OK: transformation to class member access syntax // does not occur in the template definition context; see [class.mfct.non-static] — end example]
A type is dependent if it is
  • a template parameter,
  • denoted by a dependent (qualified) name,
  • a nested class or enumeration that is a direct member of a class that is the current instantiation,
  • a cv-qualified type where the cv-unqualified type is dependent,
  • a compound type constructed from any dependent type,
  • an array type whose element type is dependent or whose bound (if any) is value-dependent,
  • a function type whose parameters include one or more function parameter packs,
  • a function type whose exception specification is value-dependent,
  • denoted by a simple-template-id in which either the template name is a template parameter or any of the template arguments is a dependent type or an expression that is type-dependent or value-dependent or is a pack expansion,131 or
  • denoted by decltype(expression), where expression is type-dependent.
[Note 3:
Because typedefs do not introduce new types, but instead simply refer to other types, a name that refers to a typedef that is a member of the current instantiation is dependent only if the type referred to is dependent.
— end note]
130)130)
Every instantiation of a class template declares a different set of assignment operators.
131)131)
This includes an injected-class-name ([class.pre]) of a class template used without a template-argument-list.

13.8.3.3 Type-dependent expressions [temp.dep.expr]

Except as described below, an expression is type-dependent if any subexpression is type-dependent.
this is type-dependent if the current class ([expr.prim.this]) is dependent ([temp.dep.type]).
An id-expression is type-dependent if it is a template-id that is not a concept-id and is dependent; or if its terminal name is
  • associated by name lookup with one or more declarations declared with a dependent type,
  • associated by name lookup with a non-type template-parameter declared with a type that contains a placeholder type,
  • associated by name lookup with a variable declared with a type that contains a placeholder type ([dcl.spec.auto]) where the initializer is type-dependent,
  • associated by name lookup with one or more declarations of member functions of a class that is the current instantiation declared with a return type that contains a placeholder type,
  • associated by name lookup with a structured binding declaration ([dcl.struct.bind]) whose brace-or-equal-initializer is type-dependent,
  • the identifier __func__ ([dcl.fct.def.general]), where any enclosing function is a template, a member of a class template, or a generic lambda,
  • a conversion-function-id that specifies a dependent type, or
  • dependent
or if it names a dependent member of the current instantiation that is a static data member of type “array of unknown bound of T” for some T ([temp.static]).
Expressions of the following forms are type-dependent only if the type specified by the type-id, simple-type-specifier or new-type-id is dependent, even if any subexpression is type-dependent:
simple-type-specifier ( expression-list )
:: new new-placement new-type-id new-initializer
:: new new-placement ( type-id ) new-initializer
dynamic_­cast < type-id > ( expression )
static_­cast < type-id > ( expression )
const_­cast < type-id > ( expression )
reinterpret_­cast < type-id > ( expression )
( type-id ) cast-expression
Expressions of the following forms are never type-dependent (because the type of the expression cannot be dependent):
literal
sizeof unary-expression
sizeof ( type-id )
sizeof ... ( identifier )
alignof ( type-id )
typeid ( expression )
typeid ( type-id )
:: delete cast-expression
:: delete [ ] cast-expression
throw assignment-expression
noexcept ( expression )
[Note 1:
For the standard library macro offsetof, see [support.types].
— end note]
A class member access expression is type-dependent if the terminal name of its id-expression, if any, is dependent or the expression refers to a member of the current instantiation and the type of the referenced member is dependent.
[Note 2:
In an expression of the form x.y or xp->y the type of the expression is usually the type of the member y of the class of x (or the class pointed to by xp).
However, if x or xp refers to a dependent type that is not the current instantiation, the type of y is always dependent.
— end note]
A braced-init-list is type-dependent if any element is type-dependent or is a pack expansion.
A fold-expression is type-dependent.

13.8.3.4 Value-dependent expressions [temp.dep.constexpr]

Except as described below, an expression used in a context where a constant expression is required is value-dependent if any subexpression is value-dependent.
An id-expression is value-dependent if:
  • it is a concept-id and any of its arguments are dependent,
  • it is type-dependent,
  • it is the name of a non-type template parameter,
  • it names a static data member that is a dependent member of the current instantiation and is not initialized in a member-declarator,
  • it names a static member function that is a dependent member of the current instantiation, or
  • it names a potentially-constant variable ([expr.const]) that is initialized with an expression that is value-dependent.
Expressions of the following form are value-dependent if the unary-expression or expression is type-dependent or the type-id is dependent:
sizeof unary-expression
sizeof ( type-id )
typeid ( expression )
typeid ( type-id )
alignof ( type-id )
noexcept ( expression )
[Note 1:
For the standard library macro offsetof, see [support.types].
— end note]
Expressions of the following form are value-dependent if either the type-id or simple-type-specifier is dependent or the expression or cast-expression is value-dependent:
simple-type-specifier ( expression-list )
static_­cast < type-id > ( expression )
const_­cast < type-id > ( expression )
reinterpret_­cast < type-id > ( expression )
( type-id ) cast-expression
Expressions of the following form are value-dependent:
sizeof ... ( identifier )
fold-expression
An expression of the form &qualified-id where the qualified-id names a dependent member of the current instantiation is value-dependent.
An expression of the form &cast-expression is also value-dependent if evaluating cast-expression as a core constant expression succeeds and the result of the evaluation refers to a templated entity that is an object with static or thread storage duration or a member function.

13.8.3.5 Dependent template arguments [temp.dep.temp]

A type template-argument is dependent if the type it specifies is dependent.
A non-type template-argument is dependent if its type is dependent or the constant expression it specifies is value-dependent.
Furthermore, a non-type template-argument is dependent if the corresponding non-type template-parameter is of reference or pointer type and the template-argument designates or points to a member of the current instantiation or a member of a dependent type.
A template template-parameter is dependent if it names a template-parameter or its terminal name is dependent.

13.8.4 Dependent name resolution [temp.dep.res]

13.8.4.1 Point of instantiation [temp.point]

For a function template specialization, a member function template specialization, or a specialization for a member function or static data member of a class template, if the specialization is implicitly instantiated because it is referenced from within another template specialization and the context from which it is referenced depends on a template parameter, the point of instantiation of the specialization is the point of instantiation of the enclosing specialization.
Otherwise, the point of instantiation for such a specialization immediately follows the namespace scope declaration or definition that refers to the specialization.
If a function template or member function of a class template is called in a way which uses the definition of a default argument of that function template or member function, the point of instantiation of the default argument is the point of instantiation of the function template or member function specialization.
For a noexcept-specifier of a function template specialization or specialization of a member function of a class template, if the noexcept-specifier is implicitly instantiated because it is needed by another template specialization and the context that requires it depends on a template parameter, the point of instantiation of the noexcept-specifier is the point of instantiation of the specialization that requires it.
Otherwise, the point of instantiation for such a noexcept-specifier immediately follows the namespace scope declaration or definition that requires the noexcept-specifier.
For a class template specialization, a class member template specialization, or a specialization for a class member of a class template, if the specialization is implicitly instantiated because it is referenced from within another template specialization, if the context from which the specialization is referenced depends on a template parameter, and if the specialization is not instantiated previous to the instantiation of the enclosing template, the point of instantiation is immediately before the point of instantiation of the enclosing template.
Otherwise, the point of instantiation for such a specialization immediately precedes the namespace scope declaration or definition that refers to the specialization.
If a virtual function is implicitly instantiated, its point of instantiation is immediately following the point of instantiation of its enclosing class template specialization.
An explicit instantiation definition is an instantiation point for the specialization or specializations specified by the explicit instantiation.
A specialization for a function template, a member function template, or of a member function or static data member of a class template may have multiple points of instantiations within a translation unit, and in addition to the points of instantiation described above,
A specialization for a class template has at most one point of instantiation within a translation unit.
A specialization for any template may have points of instantiation in multiple translation units.
If two different points of instantiation give a template specialization different meanings according to the one-definition rule, the program is ill-formed, no diagnostic required.

13.8.4.2 Candidate functions [temp.dep.candidate]

If a dependent call ([temp.dep]) would be ill-formed or would find a better match had the lookup for its dependent name considered all the function declarations with external linkage introduced in the associated namespaces in all translation units, not just considering those declarations found in the template definition and template instantiation contexts ([basic.lookup.argdep]), then the program is ill-formed, no diagnostic required.
[Example 1:

Source file "X.h":namespace Q { struct X { }; }

Source file "G.h":namespace Q { void g_impl(X, X); }

Module interface unit of M1:module; #include "X.h" #include "G.h" export module M1; export template<typename T> void g(T t) { g_impl(t, Q::X{ }); // ADL in definition context finds Q​::​g_­impl, g_­impl not discarded }

Module interface unit of M2:module; #include "X.h" export module M2; import M1; void h(Q::X x) { g(x); // OK } — end example]

[Example 2:

Module interface unit of Std:export module Std; export template<typename Iter> void indirect_swap(Iter lhs, Iter rhs) { swap(*lhs, *rhs); // swap not found by unqualified lookup, can be found only via ADL }

Module interface unit of M:export module M; import Std; struct S { /* ...*/ }; void swap(S&, S&); // #1 void f(S* p, S* q) { indirect_swap(p, q); // finds #1 via ADL in instantiation context } — end example]

[Example 3:

Source file "X.h":struct X { /* ... */ }; X operator+(X, X);

Module interface unit of F:export module F; export template<typename T> void f(T t) { t + t; }

Module interface unit of M:module; #include "X.h" export module M; import F; void g(X x) { f(x); // OK: instantiates f from F, // operator+ is visible in instantiation context } — end example]

[Example 4:

Module interface unit of A:export module A; export template<typename T> void f(T t) { cat(t, t); // #1 dog(t, t); // #2 }

Module interface unit of B:export module B; import A; export template<typename T, typename U> void g(T t, U u) { f(t); }

Source file "foo.h", not an importable header:struct foo { friend int cat(foo, foo); }; int dog(foo, foo);

Module interface unit of C1:module; #include "foo.h" // dog not referenced, discarded export module C1; import B; export template<typename T> void h(T t) { g(foo{ }, t); }

Translation unit:import C1; void i() { h(0); // error: dog not found at #2 }

Importable header "bar.h":struct bar { friend int cat(bar, bar); }; int dog(bar, bar);

Module interface unit of C2:module; #include "bar.h" // imports header unit "bar.h" export module C2; import B; export template<typename T> void j(T t) { g(bar{ }, t); }

Translation unit:import C2; void k() { j(0); // OK, dog found in instantiation context: // visible at end of module interface unit of C2 } — end example]

13.9 Template instantiation and specialization [temp.spec]

13.9.1 General [temp.spec.general]

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.
A function instantiated from a function template is called an instantiated function.
A class instantiated from a class template is called an instantiated class.
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.
A member function instantiated from a member function template is called an instantiated member function.
A member class instantiated from a member class template is called an instantiated member class.
A variable instantiated from a variable template is called an instantiated variable.
A static data member instantiated from a static data member template is called an instantiated static data member.
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.
An explicit specialization declaration is introduced by template<>.
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.
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.
[Example 1: template<class T = int> struct A { static int x; }; template<class U> void g(U) { } template<> struct A<double> { }; // specialize for T == double template<> struct A<> { }; // specialize for T == int template<> void g(char) { } // specialize for U == char // U is deduced from the parameter type template<> void g<int>(int) { } // specialize for U == int template<> int A<char>::x = 0; // specialize for T == char template<class T = int> struct B { static int x; }; template<> int B<>::x = 1; // specialize for T == int — end example]
An instantiated template specialization can be either implicitly instantiated ([temp.inst]) for a given argument list or be explicitly instantiated ([temp.explicit]).
A specialization is a class, variable, function, or class member that is either instantiated ([temp.inst]) from a templated entity or is an explicit specialization ([temp.expl.spec]) of a templated entity.
For a given template and a given set of template-arguments,
  • an explicit instantiation definition shall appear at most once in a program,
  • an explicit specialization shall be defined at most once in a program, as specified in [basic.def.odr], and
  • 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.
An implementation is not required to diagnose a violation of this rule if neither declaration is reachable from the other.
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, member-specification, enumerator-list, or static data member or variable template initializer.
[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.
— end note]
Each class template specialization instantiated from a template has its own copy of any static members.
[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 member s of type int and X<char*> has a static member s of type char*.
— end example]
If a function declaration acquired its function type through a dependent type without using the syntactic form of a function declarator, the program is ill-formed.
[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 Implicit instantiation [temp.inst]

A template specialization E is a declared specialization if there is a reachable explicit instantiation definition ([temp.explicit]) or explicit specialization declaration ([temp.expl.spec]) for E, or if there is a reachable explicit instantiation declaration for E and E is not
[Note 1:
An implicit instantiation in an importing translation unit cannot use names with internal linkage from an imported translation unit ([basic.link]).
— end note]
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.
[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.
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.
— end note]
[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]) has been declared, but not defined, at the point of instantiation ([temp.point]), the instantiation yields an incomplete class type ([basic.types]).
[Example 2: template<class T> class X; X<char> ch; // error: incomplete type X<char> — end example]
[Note 3:
Within a template declaration, a local class 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-specifiers, and non-static data member initializers, if any, but not their type-constraints or requires-clauses).
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.
— end note]
The implicit instantiation of a class template specialization causes
  • 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
  • the implicit instantiation of the definitions of deleted member functions, unscoped member enumerations, and member anonymous unions.
The implicit instantiation of a class template specialization does not cause the implicit instantiation of default arguments or noexcept-specifiers of the class member functions.
[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 point template<> 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] and [class.mem], a declaration that corresponds to a definition in the template is considered to be a definition.
[Example 4: template<class T, class U> struct Outer { template<class X, class Y> struct Inner; template<class Y> struct Inner<T, Y>; // #1a template<class Y> struct Inner<T, Y> { }; // #1b; OK: valid redeclaration of #1a template<class Y> struct Inner<U, Y> { }; // #2 }; Outer<int, int> outer; // error at #2
Outer<int, int>​::​Inner<int, Y> is redeclared at #1b.
(It is not defined but noted as being associated with a definition in Outer<T, U>.)
#2 is also a redeclaration of #1a.
It is noted as associated with a definition, so it is an invalid redeclaration of the same partial specialization.
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]
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.
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.
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.
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.
[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]) so that the body can be considered for inlining, but that no out-of-line copy of it be generated in the translation unit.
— end note]
[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 requires class Z<double>, Z<int>​::​g(), or Z<char>​::​f() to be implicitly instantiated.
— end example]
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.
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.
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]), even if constant evaluation of the expression is not required or if constant expression evaluation does not use the definition.
[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]
If the function selected by overload resolution can be determined without instantiating a class template definition, it is unspecified whether that instantiation actually takes place.
[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]
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]).
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]), unless such instantiation is required.
[Note 5:
The instantiation of a generic lambda does not require instantiation of substatements of a constexpr if statement within its compound-statement unless the call operator template is instantiated.
— 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.
The use of a template specialization in a default argument shall not cause the template to be implicitly instantiated except that a class template may be instantiated where its complete type is needed to determine the correctness of the default argument.
The use of a default argument in a function call causes specializations in the default argument to be implicitly instantiated.
If a function template f 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 template f used at that point, except that the scope in which a closure type is declared ([expr.prim.lambda.closure]) – and therefore its associated namespaces – remain as determined from the context of the definition for the default argument.
This analysis is called default argument instantiation.
The instantiated default argument is then used as the argument of f.
Each default argument is instantiated independently.
[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]
The noexcept-specifier of a function template specialization is not instantiated along with the function declaration; it is instantiated when needed ([except.spec]).
If such an noexcept-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 noexcept-specifier is done as if it were being done as part of instantiating the declaration of the specialization at that point.
[Note 6:
[temp.point] defines the point of instantiation of a template specialization.
— end note]
There is an implementation-defined quantity that specifies the limit on the total depth of recursive instantiations ([implimits]), which could involve more than one template.
The result of an infinite recursion in instantiation is undefined.
[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]
The type-constraints and requires-clause 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] and [temp.constr.atomic] when determining whether the constraints are satisfied or as specified in [temp.constr.decl] when comparing declarations.
[Note 7:
The satisfaction of constraints is determined during template argument deduction ([temp.deduct]) and overload resolution ([over.match]).
— end note]
[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.
Their constraints are not satisfied, and they suppress the implicit declaration of a default constructor for S<char> ([class.default.ctor]), so there is no viable constructor for s1.
— end example]
[Example 11: template<typename T> struct S1 { template<typename U> requires false struct 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.
S2 is ill-formed, no diagnostic required, since no substitution into the constraints of its Inner2 template would result in a valid expression.
— end example]

13.9.3 Explicit instantiation [temp.explicit]

A class, function, variable, or member template specialization can be explicitly instantiated from its template.
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.
The syntax for explicit instantiation is:
There are two forms of explicit instantiation: an explicit instantiation definition and an explicit instantiation declaration.
An explicit instantiation declaration begins with the extern keyword.
An explicit instantiation shall not use a storage-class-specifier ([dcl.stc]) other than thread_­local.
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.
No attribute-specifier-seq ([dcl.attr.grammar]) shall appertain to an explicit instantiation.
If the explicit instantiation is for a class or member class, the elaborated-type-specifier in the declaration shall include a simple-template-id; otherwise, the declaration shall be a simple-declaration whose init-declarator-list comprises a single init-declarator that does not have an initializer.
If the explicit instantiation is for a variable template specialization, the unqualified-id in the declarator shall be a simple-template-id.
[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 namespace N { template<class T> void f(T&) { } } template void N::f<int>(int&); — end example]
An explicit instantiation does not introduce a name ([basic.scope.scope]).
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.
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.
If the declaration of the explicit instantiation names an implicitly-declared special member function ([special]), the program is ill-formed.
The declaration in an explicit-instantiation and the declaration produced by the corresponding substitution into the templated function, variable, or class are two declarations of the same entity.
[Note 1:
These declarations are required to have matching types as specified in [basic.link], except as specified in [except.spec].
[Example 2: template<typename T> T var = {}; template float var<float>; // OK, instantiated variable has type float template int var<int[16]>[]; // OK, absence of major array bound is permitted template int *var<int>; // error: instantiated variable has type int template<typename T> auto av = T(); template int av<int>; // OK, variable with type int can be redeclared with type auto template<typename T> auto f() {} template void f<int>(); // error: function with deduced return type // redeclared with non-deduced return type ([dcl.spec.auto]) — end example]
— end note]
Despite its syntactic form, the declaration in an explicit-instantiation for a variable is not itself a definition and does not conflict with the definition instantiated by an explicit instantiation definition for that variable.
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.
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.
A trailing template-argument can be left unspecified in an explicit instantiation of a function template specialization or of a member function template specialization provided it can be deduced ([temp.deduct.decl]).
If all template arguments can be deduced, the empty template argument list <> may be omitted.
[Example 3: template<class T> class Array { /* ... */ }; template<class T> void sort(Array<T>& v) { /* ... */ } // instantiate sort(Array<int>&) -- template-argument deduced template void sort<>(Array<int>&); — end example]
[Note 2:
An explicit instantiation of a constrained template is required to satisfy that template's associated constraints ([temp.constr.decl]).
The satisfaction of constraints is determined when forming the template name of an explicit instantiation in which all template arguments are specified ([temp.names]), or, for explicit instantiations of function templates, during template argument deduction ([temp.deduct.decl]) when one or more trailing template arguments are left unspecified.
— end note]
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.constr]), except as described below.
[Note 3:
In addition, it will typically be an explicit instantiation of certain implementation-dependent data about the class.
— end note]
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.
An explicit instantiation of a prospective destructor ([class.dtor]) shall correspond to the selected destructor of the class.
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.
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 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.
[Note 4:
This rule does apply to inline functions even though an explicit instantiation declaration of such an entity has no other normative effect.
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.
— end note]
An explicit instantiation declaration shall not name a specialization of a template with internal linkage.
An explicit instantiation does not constitute a use of a default argument, so default argument instantiation is not done.
[Example 4: 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 Explicit specialization [temp.expl.spec]

An explicit specialization of any of the following:
  • function template
  • class template
  • variable template
  • member function of a class template
  • static data member of a class template
  • member class of a class template
  • member enumeration of a class template
  • member class template of a class or class template
  • member function template of a class or class template
can be declared by a declaration introduced by template<>; that is:
[Example 1: template<class T> class stream; template<> class stream<char> { /* ... */ }; template<class T> class Array { /* ... */ }; template<class T> void sort(Array<T>& v) { /* ... */ } template<> void sort<char*>(Array<char*>&);
Given these declarations, stream<char> will be used as the definition of streams of chars; other streams will be handled by class template specializations instantiated from the class template.
Similarly, sort<char*> will be used as the sort function for arguments of type Array<char*>; other Array types will be sorted by functions generated from the template.
— end example]
An explicit specialization shall not use a storage-class-specifier ([dcl.stc]) other than thread_­local.
An explicit specialization may be declared in any scope in which the corresponding primary template may be defined ([dcl.meaning], [class.mem], [temp.mem]).
An explicit specialization does not introduce a name ([basic.scope.scope]).
A declaration of a function template, class template, or variable template being explicitly specialized shall be reachable from the declaration of the explicit specialization.
[Note 1:
A declaration, but not a definition of the template is required.
— 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.
[Example 2: template<> class X<int> { /* ... */ }; // error: X not a template template<class T> class X; template<> class X<char*> { /* ... */ }; // OK: X is a template — end example]
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.
If such an explicit specialization for the member of a class template names an implicitly-declared special member function ([special]), the program is ill-formed.
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.
The definition of the class template explicit specialization shall be reachable from the definition of any member of it.
The definition of an explicitly specialized class is unrelated to the definition of a generated specialization.
That is, its members need not have the same names, types, etc.
as the members of a generated specialization.
Members of an explicitly specialized class template are defined in the same manner as members of normal classes, and not using the template<> syntax.
The same is true when defining a member of an explicitly specialized member class.
However, template<> is used in defining a member of an explicitly specialized member class template that is specialized as a class template.
[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 template void A<int>::f(int) { /* ... */ } template<> struct A<char>::B { void f(); }; // template<> also not used when defining a member of an explicitly specialized member class void 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 template template<> 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 permitted template<> template<class U> struct A<short>::C { void f(); }; template<class U> void A<short>::C<U>::f() { /* ... */ } // error: template<> required — end example]
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.
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.
An implicit instantiation is never generated for an explicit specialization that is declared but not defined.
[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 template template<> void sort<>(Array<char*>& v); // OK: sort<char*> not yet used template<class T> struct A { enum E : T; enum class S : T; }; template<> enum A<int>::E : int { eint }; // OK template<> enum class A<int>::S : int { sint }; // OK template<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 instantiated template<> enum class A<char>::S : char { schar }; // OK — end example]
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.
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.
A simple-template-id that names a class template explicit specialization that has been declared but not defined can be used exactly like the names of other incompletely-defined classes ([basic.types]).
[Example 5: template<class T> class X; // X is a class template template<> 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]
A trailing template-argument can be left unspecified in the template-id naming an explicit function template specialization provided it can be deduced ([temp.deduct.decl]).
[Example 6: template<class T> class Array { /* ... */ }; template<class T> void sort(Array<T>& v); // explicit specialization for sort(Array<int>&) // with deduced template-argument of type int template<> void sort(Array<int>&); — end example]
[Note 2:
An explicit specialization of a constrained template is required to satisfy that template's associated constraints ([temp.constr.decl]).
The satisfaction of constraints is determined when forming the template name of an explicit specialization in which all template arguments are specified ([temp.names]), or, for explicit specializations of function templates, during template argument deduction ([temp.deduct.decl]) when one or more trailing template arguments are left unspecified.
— end note]
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]).
Whether an explicit specialization of a function or variable template is inline, constexpr, or an immediate function is determined by the explicit specialization and is independent of those properties of the template.
[Example 7: template<class T> void f(T) { /* ... */ } template<class T> inline T g(T) { /* ... */ } template<> inline void f<>(int) { /* ... */ } // OK: inline template<> int g<>(int) { /* ... */ } // OK: not inline — end example]
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.
[Note 3:
The definition of a static data member of a template for which default-initialization is desired can use functional cast notation ([expr.type.conv]): template<> X Q<int>::x; // declaration template<> X Q<int>::x (); // error: declares a function template<> X Q<int>::x = X(); // definition
— end note]
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.
An explicit specialization of a member or member template is specified using the syntax for explicit specialization.
[Example 8: 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) { } }; // specialization template<> void A<int>::f(int); // out of class member template definition template<class T> template<class X1> void A<T>::g1(T, X1) { } // member template specialization template<> template<class X1> void A<int>::g1(int, X1); // member template specialization template<> template<> void A<int>::g1(int, char); // X1 deduced as char template<> template<> void A<int>::g2<char>(int, char); // X2 specified as char // member specialization even if defined in class definition template<> void A<int>::h(int) { } — end example]
A member or a member template may be nested within many enclosing class templates.
In an explicit specialization for such a member, the member declaration shall be preceded by a template<> for each enclosing class template that is explicitly specialized.
[Example 9: 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]
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.
In such an explicit specialization declaration, the keyword template followed by a template-parameter-list shall be provided instead of the template<> preceding the explicit specialization declaration of the member.
The types of the template-parameters in the template-parameter-list shall be the same as those specified in the primary template definition.
[Example 10: template <class T1> class A { template<class T2