[temp.decls]

# 13 Templates [[temp]](./#temp)

## 13.7 Template declarations [temp.decls]

### [13.7.1](#general) General [[temp.decls.general]](temp.decls.general)

[1](#general-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L2592)

The template parameters of a template are specified in
the angle bracket enclosed list
that immediately follows the keyword template[.](#general-1.sentence-1)

[2](#general-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L2597)

A [*primary template*](#def:template,primary "13.7.1 General [temp.decls.general]") declaration is one
in which the name of the template is not followed by
a [*template-argument-list*](temp.names#nt:template-argument-list "13.3 Names of template specializations [temp.names]")[.](#general-2.sentence-1)

The template argument list of a primary template is
the template argument list of its [*template-head*](temp.pre#nt:template-head "13.1 Preamble [temp.pre]") ([[temp.arg]](temp.arg "13.4 Template arguments"))[.](#general-2.sentence-2)

A template declaration in which the name of the template is followed by
a [*template-argument-list*](temp.names#nt:template-argument-list "13.3 Names of template specializations [temp.names]") is
a partial specialization ([[temp.spec.partial]](#temp.spec.partial "13.7.6 Partial specialization")) of
the template named in the declaration,
which shall be a class or variable template[.](#general-2.sentence-3)

[3](#general-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L2609)

For purposes of name lookup and instantiation,
default arguments,[*type-constraint*](temp.param#nt:type-constraint "13.2 Template parameters [temp.param]")*s*,[*requires-clause*](temp.pre#nt:requires-clause "13.1 Preamble [temp.pre]")*s* ([[temp.pre]](temp.pre "13.1 Preamble")),
and[*noexcept-specifier*](except.spec#nt:noexcept-specifier "14.5 Exception specifications [except.spec]")*s* of function templates
and
of member functions of class templates
are considered definitions;
each
default argument,[*type-constraint*](temp.param#nt:type-constraint "13.2 Template parameters [temp.param]"),[*requires-clause*](temp.pre#nt:requires-clause "13.1 Preamble [temp.pre]"),
or[*noexcept-specifier*](except.spec#nt:noexcept-specifier "14.5 Exception specifications [except.spec]") is a separate definition
which is unrelated
to the templated function definition or
to any other
default arguments,[*type-constraint*](temp.param#nt:type-constraint "13.2 Template parameters [temp.param]")*s*,[*requires-clause*](temp.pre#nt:requires-clause "13.1 Preamble [temp.pre]")*s*,
or[*noexcept-specifier*](except.spec#nt:noexcept-specifier "14.5 Exception specifications [except.spec]")*s*[.](#general-3.sentence-1)

For the purpose of instantiation, the substatements of a[constexpr if](stmt.if#def:constexpr_if "8.5.2 The if statement [stmt.if]") statement are considered definitions[.](#general-3.sentence-2)

For the purpose of name lookup and instantiation,
the [*compound-statement*](stmt.block#nt:compound-statement "8.4 Compound statement or block [stmt.block]") of an [*expansion-statement*](stmt.expand#nt:expansion-statement "8.7 Expansion statements [stmt.expand]") is considered a template definition[.](#general-3.sentence-3)

[4](#general-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L2641)

Because an [*alias-declaration*](dcl.pre#nt:alias-declaration "9.1 Preamble [dcl.pre]") cannot declare a[*template-id*](temp.names#nt:template-id "13.3 Names of template specializations [temp.names]"), it is not possible to partially or
explicitly specialize an alias template[.](#general-4.sentence-1)

### [13.7.2](#temp.class) Class templates [[temp.class]](temp.class)

#### [13.7.2.1](#temp.class.general) General [[temp.class.general]](temp.class.general)

[1](#temp.class.general-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L2650)

A[*class template*](#def:template,class "13.7.2.1 General [temp.class.general]") defines the layout and operations
for an unbounded set of related types[.](#temp.class.general-1.sentence-1)

[2](#temp.class.general-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L2656)

[*Example [1](#temp.class.general-example-1)*:

It is possible for a single class templateList 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[.](#temp.class.general-2.sentence-1)

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*](dcl.type.simple#nt:type-name "9.2.9.3 Simple type specifiers [dcl.type.simple]") T can be used in the declaration[.](#temp.class.general-2.sentence-3)

In other words,Array is a parameterized type withT as its parameter[.](#temp.class.general-2.sentence-4)

â *end example*]

[3](#temp.class.general-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L2686)

[*Note [1](#temp.class.general-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*](temp.pre#nt:template-head "13.1 Preamble [temp.pre]") equivalent to that
of the class template[.](#temp.class.general-3.sentence-1)

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[.](#temp.class.general-3.sentence-2)

The class template name in the member definition is followed by
the template argument list of the [*template-head*](temp.pre#nt:template-head "13.1 Preamble [temp.pre]") ([[temp.arg]](temp.arg "13.4 Template arguments"))[.](#temp.class.general-3.sentence-3)

[*Example [2](#temp.class.general-example-2)*: template<class T1, class T2> struct A {void f1(); void f2();};

template<class T2, class T1> void A<T2,T1>::f1() { } // OKtemplate<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() { } // OKtemplate<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-head*](temp.pre#nt:template-head "13.1 Preamble [temp.pre]")*s* matchtemplate<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-head*](temp.pre#nt:template-head "13.1 Preamble [temp.pre]")*s* arevoid S<T>::h() { } // functionally equivalent but not equivalenttemplate<C X> template<D Y>struct S<X>::Inner { }; // OK â *end example*]

â *end note*]

[4](#temp.class.general-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L2742)

In a partial specialization,
explicit specialization or
explicit instantiation of a class template,
the [*class-key*](class.pre#nt:class-key "11.1 Preamble [class.pre]") shall agree in kind with the original class template declaration ([[dcl.type.elab]](dcl.type.elab "9.2.9.5 Elaborated type specifiers"))[.](#temp.class.general-4.sentence-1)

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

[1](#temp.mem.func-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L2751)

A member function
of a class template
may be defined outside of the class
template definition in which it is declared[.](#temp.mem.func-1.sentence-1)

[*Example [1](#temp.mem.func-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[.](#temp.mem.func-1.sentence-2)

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> { } // OKtemplate<typename T>void S<T>::g() { } // error: no matching function in S<T>

â *end example*]

[2](#temp.mem.func-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L2796)

The[*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]")*s* for a member function of a class template are determined by the[*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]")*s* of the type of the object for which the member function is called[.](#temp.mem.func-2.sentence-1)

[*Example [2](#temp.mem.func-example-2)*:

The[*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]") forArray<T>​::​operator[] will be determined by theArray to which the subscripting operation is applied[.](#temp.mem.func-2.sentence-2)

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](#temp.deduct.guide) Deduction guides [[temp.deduct.guide]](temp.deduct.guide)

[1](#temp.deduct.guide-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L2823)

Deduction guides are used
when a [*template-name*](temp.names#nt:template-name "13.3 Names of template specializations [temp.names]") or [*splice-type-specifier*](dcl.type.splice#nt:splice-type-specifier "9.2.9.9 Type splicing [dcl.type.splice]") appears as a type specifier
for a deduced class type ([[dcl.type.class.deduct]](dcl.type.class.deduct "9.2.9.8 Deduced class template specialization types"))[.](#temp.deduct.guide-1.sentence-1)

Deduction guides are not found by name lookup[.](#temp.deduct.guide-1.sentence-2)

Instead, when performing class template argument deduction ([[over.match.class.deduct]](over.match.class.deduct "12.2.2.9 Class template argument deduction")),
all reachable deduction guides declared for the class template are considered[.](#temp.deduct.guide-1.sentence-3)

[deduction-guide:](#nt:deduction-guide "13.7.2.3 Deduction guides [temp.deduct.guide]")  
[*explicit-specifier*](dcl.fct.spec#nt:explicit-specifier "9.2.3 Function specifiers [dcl.fct.spec]")opt [*template-name*](temp.names#nt:template-name "13.3 Names of template specializations [temp.names]") ( [*parameter-declaration-clause*](dcl.fct#nt:parameter-declaration-clause "9.3.4.6 Functions [dcl.fct]") ) -> [*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]") [*requires-clause*](temp.pre#nt:requires-clause "13.1 Preamble [temp.pre]")opt ;

[2](#temp.deduct.guide-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L2837)

[*Example [1](#temp.deduct.guide-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*]

[3](#temp.deduct.guide-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L2855)

The same restrictions apply
to the [*parameter-declaration-clause*](dcl.fct#nt:parameter-declaration-clause "9.3.4.6 Functions [dcl.fct]") of a deduction guide
as in a function declaration ([[dcl.fct]](dcl.fct "9.3.4.6 Functions")),
except that a generic parameter type placeholder ([[dcl.spec.auto]](dcl.spec.auto "9.2.9.7 Placeholder type specifiers"))
shall not appear in the [*parameter-declaration-clause*](dcl.fct#nt:parameter-declaration-clause "9.3.4.6 Functions [dcl.fct]") of
a deduction guide[.](#temp.deduct.guide-3.sentence-1)

The [*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]") shall name a class template specialization[.](#temp.deduct.guide-3.sentence-2)

The [*template-name*](temp.names#nt:template-name "13.3 Names of template specializations [temp.names]") shall be the same [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") as the [*template-name*](temp.names#nt:template-name "13.3 Names of template specializations [temp.names]") of the [*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]")[.](#temp.deduct.guide-3.sentence-3)

A [*deduction-guide*](#nt:deduction-guide "13.7.2.3 Deduction guides [temp.deduct.guide]") shall inhabit the scope
to which the corresponding class template belongs
and, for a member class template, have the same access[.](#temp.deduct.guide-3.sentence-4)

Two deduction guide declarations
for the same class template
shall not have equivalent [*parameter-declaration-clause*](dcl.fct#nt:parameter-declaration-clause "9.3.4.6 Functions [dcl.fct]")*s* if either is reachable from the other[.](#temp.deduct.guide-3.sentence-5)

#### [13.7.2.4](#temp.mem.class) Member classes of class templates [[temp.mem.class]](temp.mem.class)

[1](#temp.mem.class-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L2880)

A member class of a class template may be defined outside the class template
definition in which it is declared[.](#temp.mem.class-1.sentence-1)

[*Note [1](#temp.mem.class-note-1)*:

The member class must be defined before its first use that requires
an instantiation ([[temp.inst]](temp.inst "13.9.2 Implicit instantiation"))[.](#temp.mem.class-1.sentence-2)

For example,template<class T> struct A {class B;};
A<int>::B* b1; // OK, requires A to be defined but not A​::​Btemplate<class T> class A<T>::B { };
A<int>::B b2; // OK, requires A​::​B to be defined

â *end note*]

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

[1](#temp.static-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L2899)

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[.](#temp.static-1.sentence-1)

[*Example [1](#temp.static-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*]

[2](#temp.static-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L2921)

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[.](#temp.static-2.sentence-1)

[*Example [2](#temp.static-example-2)*: template <class T> struct A {static int i[];};template <class T> int A<T>::i[4]; // 4 elementstemplate <> int A<int>::i[] = { 1 }; // OK, 1 element â *end example*]

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

[1](#temp.mem.enum-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L2936)

An enumeration member of a class template may be defined outside the class
template definition[.](#temp.mem.enum-1.sentence-1)

[*Example [1](#temp.mem.enum-example-1)*: template<class T> struct A {enum E : T;};template<class T> enum A<T>::E : T { e1, e2 };
A<int>::E e = A<int>::e1; â *end example*]

### [13.7.3](#temp.mem) Member templates [[temp.mem]](temp.mem)

[1](#temp.mem-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L2951)

A template can be declared within a class or class template; such a template
is called a member template[.](#temp.mem-1.sentence-1)

A member template can be defined within or outside its class definition or
class template definition[.](#temp.mem-1.sentence-2)

A member template of a class template that is defined outside of its class
template definition shall be specified with
a [*template-head*](temp.pre#nt:template-head "13.1 Preamble [temp.pre]") equivalent to that
of the class template followed by
a [*template-head*](temp.pre#nt:template-head "13.1 Preamble [temp.pre]") equivalent to that
of the member template ([[temp.over.link]](#temp.over.link "13.7.7.2 Function template overloading"))[.](#temp.mem-1.sentence-3)

[*Example [1](#temp.mem-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](#temp.mem-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) { } // OKtemplate<C1 T> template<typename U>void S<T>::g(U) { } // error: no matching function in S<T> â *end example*]

[2](#temp.mem-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L2990)

A local class of non-closure type shall not have member templates[.](#temp.mem-2.sentence-1)

[Access control rules](class.access "11.8 Member access control [class.access]") apply to member template names[.](#temp.mem-2.sentence-2)

A destructor shall not be a member
template[.](#temp.mem-2.sentence-3)

A non-template member function ([[dcl.fct]](dcl.fct "9.3.4.6 Functions")) 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[.](#temp.mem-2.sentence-4)

When both exist, a use of that name and type refers to the
non-template member unless an explicit template argument list is supplied[.](#temp.mem-2.sentence-5)

[*Example [3](#temp.mem-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 functiontemplate <> template <> void A<int>::f<>(int) { } // member function template specializationint main() { A<char> ac;
 ac.f(1); // non-template ac.f('c'); // template ac.f<>(1); // template} â *end example*]

[3](#temp.mem-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3021)

A member function template shall not be declared virtual[.](#temp.mem-3.sentence-1)

[*Example [4](#temp.mem-example-4)*: template <class T> struct AA {template <class C> virtual void g(C); // errorvirtual void f(); // OK}; â *end example*]

[4](#temp.mem-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3032)

A specialization of
a member function template does not override a virtual function from a
base class[.](#temp.mem-4.sentence-1)

[*Example [5](#temp.mem-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*]

[5](#temp.mem-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3049)

[*Note [1](#temp.mem-note-1)*:

A specialization of a
conversion function template
is named in
the same way as a non-template conversion function that converts to
the same type ([[class.conv.fct]](class.conv.fct "11.4.8.3 Conversion functions"))[.](#temp.mem-5.sentence-1)

[*Example [6](#temp.mem-example-6)*: struct A {template <class T> operator T*();};template <class T> A::operator T*() { return 0; }template <> A::operator char*() { return 0; } // specializationtemplate A::operator void*(); // explicit instantiationint main() { A a; int* ip;
 ip = a.operator int*(); // explicit call to template operator A​::​operator int*()} â *end example*]

An expression designating
a particular specialization of a conversion function template
can only be formed with a [*splice-expression*](expr.prim.splice#nt:splice-expression "7.5.9 Expression splicing [expr.prim.splice]")[.](#temp.mem-5.sentence-2)

There is no analogous syntax to form a [*template-id*](temp.names#nt:template-id "13.3 Names of template specializations [temp.names]") ([[temp.names]](temp.names "13.3 Names of template specializations"))
for such a function
by providing an explicit template argument list ([[temp.arg.explicit]](temp.arg.explicit "13.10.2 Explicit template argument specification"))[.](#temp.mem-5.sentence-3)

â *end note*]

### [13.7.4](#temp.variadic) Variadic templates [[temp.variadic]](temp.variadic)

[1](#temp.variadic-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3082)

A [*template parameter pack*](#def:template_parameter_pack "13.7.4 Variadic templates [temp.variadic]") is a template parameter
that accepts zero or more template arguments[.](#temp.variadic-1.sentence-1)

[*Example [1](#temp.variadic-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*]

[2](#temp.variadic-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3096)

A [*function parameter pack*](#def:function_parameter_pack "13.7.4 Variadic templates [temp.variadic]") is a function parameter
that accepts zero or more function arguments[.](#temp.variadic-2.sentence-1)

[*Example [2](#temp.variadic-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*]

[3](#temp.variadic-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3109)

An [](#def:init-capture_pack "13.7.4 Variadic templates [temp.variadic]")*[*init-capture*](expr.prim.lambda.capture#nt:init-capture "7.5.6.3 Captures [expr.prim.lambda.capture]") pack* is a lambda capture that introduces an [*init-capture*](expr.prim.lambda.capture#nt:init-capture "7.5.6.3 Captures [expr.prim.lambda.capture]") for each of the elements in the pack expansion of its [*initializer*](dcl.init.general#nt:initializer "9.5.1 General [dcl.init.general]")[.](#temp.variadic-3.sentence-1)

[*Example [3](#temp.variadic-example-3)*: template <typename... Args>void foo(Args... args) {[...xs=args]{ bar(xs...); // xs is an [*init-capture*](expr.prim.lambda.capture#nt:init-capture "7.5.6.3 Captures [expr.prim.lambda.capture]") pack};} foo(); // xs contains zero [*init-capture*](expr.prim.lambda.capture#nt:init-capture "7.5.6.3 Captures [expr.prim.lambda.capture]")*s* foo(1); // xs contains one [*init-capture*](expr.prim.lambda.capture#nt:init-capture "7.5.6.3 Captures [expr.prim.lambda.capture]") â *end example*]

[4](#temp.variadic-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3127)

A [*structured binding pack*](#def:structured_binding_pack "13.7.4 Variadic templates [temp.variadic]") is an [*sb-identifier*](dcl.pre#nt:sb-identifier "9.1 Preamble [dcl.pre]") that introduces zero or more structured bindings ([[dcl.struct.bind]](dcl.struct.bind "9.7 Structured binding declarations"))[.](#temp.variadic-4.sentence-1)

[*Example [4](#temp.variadic-example-4)*: auto foo() -> int(&)[2];

template <class T>void g() {auto [...a] = foo(); // a is a structured binding pack containing two elementsauto [b, c, ...d] = foo(); // d is a structured binding pack containing zero elements} â *end example*]

[5](#temp.variadic-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3142)

A [*pack*](#def:pack "13.7.4 Variadic templates [temp.variadic]") is
a template parameter pack,
a function parameter pack,
an [*init-capture*](expr.prim.lambda.capture#nt:init-capture "7.5.6.3 Captures [expr.prim.lambda.capture]") pack, or
a structured binding pack[.](#temp.variadic-5.sentence-1)

The number of elements of a template parameter pack
or a function parameter pack
is the number of arguments provided for the parameter pack[.](#temp.variadic-5.sentence-2)

The number of elements of an [*init-capture*](expr.prim.lambda.capture#nt:init-capture "7.5.6.3 Captures [expr.prim.lambda.capture]") pack
is the number of elements in the pack expansion of its [*initializer*](dcl.init.general#nt:initializer "9.5.1 General [dcl.init.general]")[.](#temp.variadic-5.sentence-3)

[6](#temp.variadic-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3154)

A [*pack expansion*](#def:pack_expansion "13.7.4 Variadic templates [temp.variadic]") consists of a [*pattern*](#def:pack_expansion,pattern "13.7.4 Variadic templates [temp.variadic]") and an ellipsis, the instantiation of which
produces zero or more instantiations of the pattern in a list (described below)[.](#temp.variadic-6.sentence-1)

The form of the pattern
depends on the context in which the expansion occurs[.](#temp.variadic-6.sentence-2)

Pack
expansions can occur in the following contexts:

- [(6.1)](#temp.variadic-6.1)

  In a function parameter pack ([[dcl.fct]](dcl.fct "9.3.4.6 Functions")); the pattern is the[*parameter-declaration*](dcl.fct#nt:parameter-declaration "9.3.4.6 Functions [dcl.fct]") without the ellipsis[.](#temp.variadic-6.1.sentence-1)

- [(6.2)](#temp.variadic-6.2)

  In a [*using-declaration*](namespace.udecl#nt:using-declaration "9.10 The using declaration [namespace.udecl]") ([[namespace.udecl]](namespace.udecl "9.10 The using declaration"));
the pattern is a [*using-declarator*](namespace.udecl#nt:using-declarator "9.10 The using declaration [namespace.udecl]")[.](#temp.variadic-6.2.sentence-1)

- [(6.3)](#temp.variadic-6.3)

  In a [*friend-type-declaration*](class.mem.general#nt:friend-type-declaration "11.4.1 General [class.mem.general]") ([[class.mem.general]](class.mem.general "11.4.1 General"));
the pattern is a [*friend-type-specifier*](class.mem.general#nt:friend-type-specifier "11.4.1 General [class.mem.general]")[.](#temp.variadic-6.3.sentence-1)

- [(6.4)](#temp.variadic-6.4)

  In a template parameter pack that is a pack expansion ([[temp.param]](temp.param "13.2 Template parameters")):
  * [(6.4.1)](#temp.variadic-6.4.1)

if the template parameter pack is a [*parameter-declaration*](dcl.fct#nt:parameter-declaration "9.3.4.6 Functions [dcl.fct]");
the pattern is the [*parameter-declaration*](dcl.fct#nt:parameter-declaration "9.3.4.6 Functions [dcl.fct]") without the ellipsis;

  * [(6.4.2)](#temp.variadic-6.4.2)

if the template parameter pack is a [*type-parameter*](temp.param#nt:type-parameter "13.2 Template parameters [temp.param]");
the pattern is the corresponding [*type-parameter*](temp.param#nt:type-parameter "13.2 Template parameters [temp.param]") without the ellipsis;

  * [(6.4.3)](#temp.variadic-6.4.3)

if the template parameter pack is a template template parameter;
the pattern is the corresponding[*type-tt-parameter*](temp.param#nt:type-tt-parameter "13.2 Template parameters [temp.param]"),[*variable-tt-parameter*](temp.param#nt:variable-tt-parameter "13.2 Template parameters [temp.param]"), or[*concept-tt-parameter*](temp.param#nt:concept-tt-parameter "13.2 Template parameters [temp.param]") without the ellipsis[.](#temp.variadic-6.4.sentence-1)

- [(6.5)](#temp.variadic-6.5)

  In an [*initializer-list*](dcl.init.general#nt:initializer-list "9.5.1 General [dcl.init.general]") ([[dcl.init]](dcl.init "9.5 Initializers"));
the pattern is an [*initializer-clause*](dcl.init.general#nt:initializer-clause "9.5.1 General [dcl.init.general]")[.](#temp.variadic-6.5.sentence-1)

- [(6.6)](#temp.variadic-6.6)

  In a [*base-specifier-list*](class.derived.general#nt:base-specifier-list "11.7.1 General [class.derived.general]") ([[class.derived]](class.derived "11.7 Derived classes"));
the pattern is a [*base-specifier*](class.derived.general#nt:base-specifier "11.7.1 General [class.derived.general]")[.](#temp.variadic-6.6.sentence-1)

- [(6.7)](#temp.variadic-6.7)

  In a [*mem-initializer-list*](class.base.init#nt:mem-initializer-list "11.9.3 Initializing bases and members [class.base.init]") ([[class.base.init]](class.base.init "11.9.3 Initializing bases and members")) for a[*mem-initializer*](class.base.init#nt:mem-initializer "11.9.3 Initializing bases and members [class.base.init]") whose [*mem-initializer-id*](class.base.init#nt:mem-initializer-id "11.9.3 Initializing bases and members [class.base.init]") denotes a
base class; the pattern is the [*mem-initializer*](class.base.init#nt:mem-initializer "11.9.3 Initializing bases and members [class.base.init]")[.](#temp.variadic-6.7.sentence-1)

- [(6.8)](#temp.variadic-6.8)

  In a [*template-argument-list*](temp.names#nt:template-argument-list "13.3 Names of template specializations [temp.names]") ([[temp.arg]](temp.arg "13.4 Template arguments"));
the pattern is a [*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]")[.](#temp.variadic-6.8.sentence-1)

- [(6.9)](#temp.variadic-6.9)

  In an [*attribute-list*](dcl.attr.grammar#nt:attribute-list "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") ([[dcl.attr.grammar]](dcl.attr.grammar "9.13.1 Attribute syntax and semantics"));
the pattern is an [*attribute*](dcl.attr.grammar#nt:attribute "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")[.](#temp.variadic-6.9.sentence-1)

- [(6.10)](#temp.variadic-6.10)

  In an [*annotation-list*](dcl.attr.grammar#nt:annotation-list "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") ([[dcl.attr.grammar]](dcl.attr.grammar "9.13.1 Attribute syntax and semantics"));
the pattern is an [*annotation*](dcl.attr.grammar#nt:annotation "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")[.](#temp.variadic-6.10.sentence-1)

- [(6.11)](#temp.variadic-6.11)

  In an [*alignment-specifier*](dcl.attr.grammar#nt:alignment-specifier "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") ([[dcl.align]](dcl.align "9.13.2 Alignment specifier")); the pattern is
the [*alignment-specifier*](dcl.attr.grammar#nt:alignment-specifier "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") without the ellipsis[.](#temp.variadic-6.11.sentence-1)

- [(6.12)](#temp.variadic-6.12)

  In a [*capture-list*](expr.prim.lambda.capture#nt:capture-list "7.5.6.3 Captures [expr.prim.lambda.capture]") ([[expr.prim.lambda.capture]](expr.prim.lambda.capture "7.5.6.3 Captures")); the pattern is
the [*capture*](expr.prim.lambda.capture#nt:capture "7.5.6.3 Captures [expr.prim.lambda.capture]") without the ellipsis[.](#temp.variadic-6.12.sentence-1)

- [(6.13)](#temp.variadic-6.13)

  In a [sizeof... expression](expr.sizeof "7.6.2.5 Sizeof [expr.sizeof]"); the pattern is an[*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]")[.](#temp.variadic-6.13.sentence-1)

- [(6.14)](#temp.variadic-6.14)

  In a [*pack-index-expression*](expr.prim.pack.index#nt:pack-index-expression "7.5.5.4 Pack indexing expression [expr.prim.pack.index]");
the pattern is an [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]")[.](#temp.variadic-6.14.sentence-1)

- [(6.15)](#temp.variadic-6.15)

  In a [*pack-index-specifier*](dcl.type.pack.index#nt:pack-index-specifier "9.2.9.4 Pack indexing specifier [dcl.type.pack.index]");
the pattern is a [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]")[.](#temp.variadic-6.15.sentence-1)

- [(6.16)](#temp.variadic-6.16)

  In a [*fold-expression*](expr.prim.fold#nt:fold-expression "7.5.7 Fold expressions [expr.prim.fold]") ([[expr.prim.fold]](expr.prim.fold "7.5.7 Fold expressions"));
the pattern is the [*cast-expression*](expr.cast#nt:cast-expression "7.6.3 Explicit type conversion (cast notation) [expr.cast]") that contains an unexpanded pack[.](#temp.variadic-6.16.sentence-1)

- [(6.17)](#temp.variadic-6.17)

  In a fold expanded constraint ([[temp.constr.fold]](temp.constr.fold "13.5.2.5 Fold expanded constraint"));
the pattern is the constraint of that fold expanded constraint[.](#temp.variadic-6.17.sentence-1)

[*Example [5](#temp.variadic-example-5)*: 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*]

[7](#temp.variadic-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3244)

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[.](#temp.variadic-7.sentence-1)

[8](#temp.variadic-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3250)

A pack whose name appears within the pattern of a pack
expansion is expanded by that pack expansion[.](#temp.variadic-8.sentence-1)

An appearance of the name of
a pack is only expanded by the innermost enclosing pack expansion[.](#temp.variadic-8.sentence-2)

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*](#def:pack,unexpanded "13.7.4 Variadic templates [temp.variadic]") in the pattern[.](#temp.variadic-8.sentence-3)

All of the packs expanded
by a pack expansion shall have the same number of arguments specified[.](#temp.variadic-8.sentence-4)

An
appearance of a name of a pack that is not expanded is
ill-formed[.](#temp.variadic-8.sentence-5)

[*Example [6](#temp.variadic-example-6)*: 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 Args2template<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*]

[9](#temp.variadic-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3287)

The instantiation of a pack expansion considers
items E1,E2,â¦,EN,
whereN is the number of elements in the pack expansion parameters[.](#temp.variadic-9.sentence-1)

Each Ei is generated by instantiating the pattern and
replacing each pack expansion parameter with its ith element[.](#temp.variadic-9.sentence-2)

Such an element, in the context of the instantiation, is interpreted as
follows:

- [(9.1)](#temp.variadic-9.1)

if the pack is a template parameter pack, the element is
  * [(9.1.1)](#temp.variadic-9.1.1)

a [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]") for a type template parameter pack,

  * [(9.1.2)](#temp.variadic-9.1.2)

an [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") for a constant template parameter pack, or

  * [(9.1.3)](#temp.variadic-9.1.3)

a [*template-name*](temp.names#nt:template-name "13.3 Names of template specializations [temp.names]") for a template template parameter pack

designating the ith corresponding
type, constant, or template template argument;

- [(9.2)](#temp.variadic-9.2)

if the pack is a function parameter pack, the element is an[*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") designating the ith function parameter
that resulted from instantiation of
the function parameter pack declaration;

- [(9.3)](#temp.variadic-9.3)

if the pack is an [*init-capture*](expr.prim.lambda.capture#nt:init-capture "7.5.6.3 Captures [expr.prim.lambda.capture]") pack,
the element is an [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") designating the variable introduced by
the ith [*init-capture*](expr.prim.lambda.capture#nt:init-capture "7.5.6.3 Captures [expr.prim.lambda.capture]") that resulted from instantiation of
the [*init-capture*](expr.prim.lambda.capture#nt:init-capture "7.5.6.3 Captures [expr.prim.lambda.capture]") pack declaration;
otherwise

- [(9.4)](#temp.variadic-9.4)

if the pack is a structured binding pack,
the element is an [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") designating the ith structured binding in the pack
that resulted from the structured binding declaration.

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[.](#temp.variadic-9.sentence-4)

[10](#temp.variadic-10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3338)

The instantiation of a sizeof... expression ([[expr.sizeof]](expr.sizeof "7.6.2.5 Sizeof")) produces
an integral constant with value N[.](#temp.variadic-10.sentence-1)

[11](#temp.variadic-11)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3342)

When instantiating a [*pack-index-expression*](expr.prim.pack.index#nt:pack-index-expression "7.5.5.4 Pack indexing expression [expr.prim.pack.index]") P,
let K be the index of P[.](#temp.variadic-11.sentence-1)

The instantiation of P is the [*id-expression*](expr.prim.id.general#nt:id-expression "7.5.5.1 General [expr.prim.id.general]") EK[.](#temp.variadic-11.sentence-2)

[12](#temp.variadic-12)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3347)

When instantiating a [*pack-index-specifier*](dcl.type.pack.index#nt:pack-index-specifier "9.2.9.4 Pack indexing specifier [dcl.type.pack.index]") P,
let K be the index of P[.](#temp.variadic-12.sentence-1)

The instantiation of P is the [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]") EK[.](#temp.variadic-12.sentence-2)

[13](#temp.variadic-13)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3352)

The instantiation of an [*alignment-specifier*](dcl.attr.grammar#nt:alignment-specifier "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") with an ellipsis
produces E1 E2 … EN[.](#temp.variadic-13.sentence-1)

[14](#temp.variadic-14)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3356)

The instantiation of a [*fold-expression*](expr.prim.fold#nt:fold-expression "7.5.7 Fold expressions [expr.prim.fold]") ([[expr.prim.fold]](expr.prim.fold "7.5.7 Fold expressions")) produces:

- [(14.1)](#temp.variadic-14.1)

( ((E1*op* E2)*op* â¯)*op* EN) for a unary left fold,

- [(14.2)](#temp.variadic-14.2)

( E1 *op*(â¯ *op*(ENâ1 *op*EN))) for a unary right fold,

- [(14.3)](#temp.variadic-14.3)

( (((E*op* E1)*op* E2)*op* â¯)*op* EN) for a binary left fold, and

- [(14.4)](#temp.variadic-14.4)

( E1 *op*(â¯ *op*(ENâ1 *op*(EN *op*E)))) for a binary right fold[.](#temp.variadic-14.sentence-1)

In each case,*op* is the [*fold-operator*](expr.prim.fold#nt:fold-operator "7.5.7 Fold expressions [expr.prim.fold]")[.](#temp.variadic-14.sentence-2)

For a binary fold,E is generated
by instantiating the [*cast-expression*](expr.cast#nt:cast-expression "7.6.3 Explicit type conversion (cast notation) [expr.cast]") that did not contain an unexpanded pack[.](#temp.variadic-14.sentence-3)

[*Example [7](#temp.variadic-example-7)*: 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[.](#temp.variadic-14.sentence-4)

â *end example*]

If N is zero for a unary fold,
the value of the expression is shown in Table [20](#tab:temp.fold.empty "Table 20: Value of folding empty sequences");
if the operator is not listed in Table [20](#tab:temp.fold.empty "Table 20: Value of folding empty sequences"),
the instantiation is ill-formed[.](#temp.variadic-14.sentence-5)

Table [20](#tab:temp.fold.empty) — Value of folding empty sequences [[tab:temp.fold.empty]](./tab:temp.fold.empty)  

| [ð](#tab:temp.fold.empty-row-1)<br>**Operator** | **Value when pack is empty** |
| --- | --- |
| [ð](#tab:temp.fold.empty-row-2)<br>&& | true |
| [ð](#tab:temp.fold.empty-row-3)<br>|| | false |
| [ð](#tab:temp.fold.empty-row-4)<br>, | void() |

[15](#temp.variadic-15)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3430)

A fold expanded constraint is not instantiated ([[temp.constr.fold]](temp.constr.fold "13.5.2.5 Fold expanded constraint"))[.](#temp.variadic-15.sentence-1)

[16](#temp.variadic-16)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3433)

The instantiation of any other pack expansion
produces a list of elements E1,E2,â¦,EN[.](#temp.variadic-16.sentence-1)

[*Note [1](#temp.variadic-note-1)*:

The variety of list varies with the context:[*expression-list*](expr.post.general#nt:expression-list "7.6.1.1 General [expr.post.general]"),[*base-specifier-list*](class.derived.general#nt:base-specifier-list "11.7.1 General [class.derived.general]"),[*template-argument-list*](temp.names#nt:template-argument-list "13.3 Names of template specializations [temp.names]"), etc[.](#temp.variadic-16.sentence-2)

â *end note*]

When N is zero, the instantiation of the expansion produces an empty list[.](#temp.variadic-16.sentence-3)

[*Example [8](#temp.variadic-example-8)*: 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](#temp.friend) Friends [[temp.friend]](temp.friend)

[1](#temp.friend-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3457)

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[.](#temp.friend-1.sentence-1)

[*Example [1](#temp.friend-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 thetask class template has the functionnext_time as a friend;
becauseprocess does not have explicit[*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]")*s*,
each specialization of thetask class template has an appropriately typed functionprocess as a friend, and this friend is not a function template specialization;
because the friendpreempt has an explicit[*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]")T,
each specialization of thetask class template has the appropriate specialization of the function
templatepreempt as a friend;
and each specialization of thetask class template has all specializations of the function templatefunc as friends[.](#temp.friend-1.sentence-2)

Similarly,
each specialization of thetask class template has the class template specializationtask<int> as a friend, and has all specializations of the class templatefrd as friends[.](#temp.friend-1.sentence-3)

â *end example*]

[2](#temp.friend-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3519)

Friend classes, class templates, functions, or function templates
can be declared within a class template[.](#temp.friend-2.sentence-1)

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[.](#temp.friend-2.sentence-2)

[*Note [1](#temp.friend-note-1)*:

They can introduce entities
that belong to an enclosing namespace scope ([[dcl.meaning]](dcl.meaning "9.3.4 Meaning of declarators")),
in which case they are attached to
the same module as the class template ([[module.unit]](module.unit "10.1 Module units and purviews"))[.](#temp.friend-2.sentence-3)

â *end note*]

[3](#temp.friend-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3533)

A friend template may be declared within a class or class template[.](#temp.friend-3.sentence-1)

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[.](#temp.friend-3.sentence-2)

In these cases, all specializations of the friend class or friend function
template are friends of the class or class template granting friendship[.](#temp.friend-3.sentence-3)

[*Example [2](#temp.friend-example-2)*: class A {template<class T> friend class B; // OKtemplate<class T> friend void f(T) { /* ... */ } // OK}; â *end example*]

[4](#temp.friend-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3549)

A template friend declaration specifies that all specializations of that
template, whether they are implicitly instantiated ([[temp.inst]](temp.inst "13.9.2 Implicit instantiation")), partially
specialized ([[temp.spec.partial]](#temp.spec.partial "13.7.6 Partial specialization")) or explicitly specialized ([[temp.expl.spec]](temp.expl.spec "13.9.4 Explicit specialization")),
are friends of the class containing the template friend declaration[.](#temp.friend-4.sentence-1)

[*Example [3](#temp.friend-example-3)*: class X {template<class T> friend struct A; class Y { };};

template<class T> struct A { X::Y ab; }; // OKtemplate<class T> struct A<T*> { X::Y ab; }; // OK â *end example*]

[5](#temp.friend-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3566)

A template friend declaration may declare
a member of a dependent type to be a friend[.](#temp.friend-5.sentence-1)

The friend declaration shall declare a function or
specify a type with an [*elaborated-type-specifier*](dcl.type.elab#nt:elaborated-type-specifier "9.2.9.5 Elaborated type specifiers [dcl.type.elab]"),
in either case with a [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") ending with a [*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]"), *C*,
whose [*template-name*](temp.names#nt:template-name "13.3 Names of template specializations [temp.names]") names a class template[.](#temp.friend-5.sentence-2)

The template parameters of the template friend declaration
shall be deducible from *C* ([[temp.deduct.type]](temp.deduct.type "13.10.3.6 Deducing template arguments from a type"))[.](#temp.friend-5.sentence-3)

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[.](#temp.friend-5.sentence-4)

[*Example [4](#temp.friend-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>​::​Btemplate<class T> friend void A<T>::f(); // does not grant friendship to A<int>​::​f()// because its return type does not matchtemplate<class T> friend void A<T>::D::g(); // error: A<T>​::​D does not end with a [*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]")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() andfriend T A<T>::i(); // to A<int>​::​i(), and thereby to all specializations}; // of those function templates â *end example*]

[6](#temp.friend-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3620)

A friend template shall not be declared in a local class[.](#temp.friend-6.sentence-1)

[7](#temp.friend-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3623)

Friend declarations shall not declare partial specializations[.](#temp.friend-7.sentence-1)

[*Example [5](#temp.friend-example-5)*: template<class T> class A { };class X {template<class T> friend class A<T*>; // error}; â *end example*]

[8](#temp.friend-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3634)

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[.](#temp.friend-8.sentence-1)

[9](#temp.friend-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3641)

A non-template friend declaration
with a [*requires-clause*](temp.pre#nt:requires-clause "13.1 Preamble [temp.pre]") shall be a definition[.](#temp.friend-9.sentence-1)

A friend function template
with a constraint that depends on a template parameter from an enclosing template
shall be a definition[.](#temp.friend-9.sentence-2)

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[.](#temp.friend-9.sentence-3)

### [13.7.6](#temp.spec.partial) Partial specialization [[temp.spec.partial]](temp.spec.partial)

#### [13.7.6.1](#temp.spec.partial.general) General [[temp.spec.partial.general]](temp.spec.partial.general)

[1](#temp.spec.partial.general-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3655)

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]](#temp.spec.partial.match "13.7.6.2 Matching of partial specializations"))[.](#temp.spec.partial.general-1.sentence-1)

A declaration of the primary template shall precede
any partial specialization of
that template[.](#temp.spec.partial.general-1.sentence-2)

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[.](#temp.spec.partial.general-1.sentence-3)

[2](#temp.spec.partial.general-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3668)

Two partial specialization declarations declare the same entity
if they are partial specializations of the same template and have equivalent[*template-head*](temp.pre#nt:template-head "13.1 Preamble [temp.pre]")*s* and template argument lists ([[temp.over.link]](#temp.over.link "13.7.7.2 Function template overloading"))[.](#temp.spec.partial.general-2.sentence-1)

Each partial specialization is a distinct template[.](#temp.spec.partial.general-2.sentence-2)

[3](#temp.spec.partial.general-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3674)

[*Example [1](#temp.spec.partial.general-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[.](#temp.spec.partial.general-3.sentence-1)

The second and subsequent declarations declare partial specializations of
the primary template[.](#temp.spec.partial.general-3.sentence-2)

â *end example*]

[4](#temp.spec.partial.general-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3689)

A partial specialization may be constrained ([[temp.constr]](temp.constr "13.5 Template constraints"))[.](#temp.spec.partial.general-4.sentence-1)

[*Example [2](#temp.spec.partial.general-example-2)*: template<typename T> concept C = true;

template<typename T> struct X { };template<typename T> struct X<T*> { }; // #1template<C T> struct X<T> { }; // #2

Both partial specializations are more specialized than the primary template[.](#temp.spec.partial.general-4.sentence-2)

#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[.](#temp.spec.partial.general-4.sentence-3)

#2 is more specialized because the template arguments are equivalent,
but the partial specialization is more constrained ([[temp.constr.order]](temp.constr.order "13.5.5 Partial ordering by constraints"))[.](#temp.spec.partial.general-4.sentence-4)

â *end example*]

[5](#temp.spec.partial.general-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3707)

The template argument list of a partial specialization is
the [*template-argument-list*](temp.names#nt:template-argument-list "13.3 Names of template specializations [temp.names]") following the name of the template[.](#temp.spec.partial.general-5.sentence-1)

[6](#temp.spec.partial.general-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3711)

A partial specialization may be declared in any
scope in which the corresponding primary template
may be defined ([[dcl.meaning]](dcl.meaning "9.3.4 Meaning of declarators"), [[class.mem]](class.mem "11.4 Class members"), [[temp.mem]](#temp.mem "13.7.3 Member templates"))[.](#temp.spec.partial.general-6.sentence-1)

[*Example [3](#temp.spec.partial.general-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*]

[7](#temp.spec.partial.general-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3732)

Partial specialization declarations do not introduce a name[.](#temp.spec.partial.general-7.sentence-1)

Instead, when the primary template name is used, any reachable partial
specializations of the primary template are also considered[.](#temp.spec.partial.general-7.sentence-2)

[*Note [1](#temp.spec.partial.general-note-1)*:

One consequence is
that a [*using-declaration*](namespace.udecl#nt:using-declaration "9.10 The using declaration [namespace.udecl]") which refers to a class template does not restrict the set of partial specializations
that are found through the [*using-declaration*](namespace.udecl#nt:using-declaration "9.10 The using declaration [namespace.udecl]")[.](#temp.spec.partial.general-7.sentence-3)

â *end note*]

[*Example [4](#temp.spec.partial.general-example-4)*: namespace N {template<class T1, class T2> class A { }; // primary template}using N::A; // refers to the primary templatenamespace 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*]

[8](#temp.spec.partial.general-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3759)

A constant template argument is non-specialized if it is the name of a constant
template parameter[.](#temp.spec.partial.general-8.sentence-1)

All other constant template arguments are specialized[.](#temp.spec.partial.general-8.sentence-2)

[9](#temp.spec.partial.general-9)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3764)

Within the argument list of a partial specialization,
the following restrictions apply:

- [(9.1)](#temp.spec.partial.general-9.1)

  The type of a template parameter corresponding to a specialized constant template
argument shall not be dependent on a parameter of the partial specialization[.](#temp.spec.partial.general-9.1.sentence-1)
  [*Example [5](#temp.spec.partial.general-example-5)*: template <class T, T t> struct C {};template <class T> struct C<T, 1>; // errortemplate< int X, int (*array_ptr)[X] > class A {};int array[5];template< int X > class A<X,&array> { }; // error â *end example*]

- [(9.2)](#temp.spec.partial.general-9.2)

  The partial specialization shall be more specialized than the primary
template ([[temp.spec.partial.order]](#temp.spec.partial.order "13.7.6.3 Partial ordering of partial specializations"))[.](#temp.spec.partial.general-9.2.sentence-1)

- [(9.3)](#temp.spec.partial.general-9.3)

  The template parameter list of a partial specialization shall not contain default
template argument values[.](#temp.spec.partial.general-9.3.sentence-1)[114](#footnote-114 "There is no context in which they would be used.")

- [(9.4)](#temp.spec.partial.general-9.4)

  An argument shall not contain an unexpanded pack[.](#temp.spec.partial.general-9.4.sentence-1)
  If
an argument is a pack expansion ([[temp.variadic]](#temp.variadic "13.7.4 Variadic templates")), it shall be
the last argument in the template argument list[.](#temp.spec.partial.general-9.4.sentence-2)

[10](#temp.spec.partial.general-10)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3797)

The usual access checking rules do not apply to non-dependent names
used to specify template arguments of the [*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]") of the partial specialization[.](#temp.spec.partial.general-10.sentence-1)

[*Note [2](#temp.spec.partial.general-note-2)*:

The template arguments can be private types or
objects that would normally not be accessible[.](#temp.spec.partial.general-10.sentence-2)

Dependent names cannot be checked when declaring the partial specialization,
but will be checked when substituting into the partial specialization[.](#temp.spec.partial.general-10.sentence-3)

â *end note*]

[114)](#footnote-114)[114)](#footnoteref-114)

There is no context in which they would be used[.](#footnote-114.sentence-1)

#### [13.7.6.2](#temp.spec.partial.match) Matching of partial specializations [[temp.spec.partial.match]](temp.spec.partial.match)

[1](#temp.spec.partial.match-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3810)

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[.](#temp.spec.partial.match-1.sentence-1)

This is done by matching the template arguments of the template
specialization with the template argument lists of the partial
specializations[.](#temp.spec.partial.match-1.sentence-2)

- [(1.1)](#temp.spec.partial.match-1.1)

  If exactly one matching partial specialization is found, the instantiation is
generated from that partial specialization[.](#temp.spec.partial.match-1.1.sentence-1)

- [(1.2)](#temp.spec.partial.match-1.2)

  If more than one matching partial specialization is found,
the partial order rules ([[temp.spec.partial.order]](#temp.spec.partial.order "13.7.6.3 Partial ordering of partial specializations")) are used to determine
whether one of the partial specializations is more specialized than the
others[.](#temp.spec.partial.match-1.2.sentence-1)
  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[.](#temp.spec.partial.match-1.2.sentence-2)

- [(1.3)](#temp.spec.partial.match-1.3)

  If no matches are found, the instantiation is generated from the
primary template[.](#temp.spec.partial.match-1.3.sentence-1)

[2](#temp.spec.partial.match-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3836)

A partial specialization matches a given actual template argument
list if the template arguments of the partial specialization can be[deduced](temp.deduct "13.10.3 Template argument deduction [temp.deduct]") from the actual template argument list,
and the deduced template arguments satisfy the [associated constraints](temp.constr.decl#def:associated_constraints "13.5.3 Constrained declarations [temp.constr.decl]") of the partial specialization, if any[.](#temp.spec.partial.match-2.sentence-1)

[*Example [1](#temp.spec.partial.match-example-1)*: template<class T1, class T2, int I> class A { }; // #1template<class T, int I> class A<T, T*, I> { }; // #2template<class T1, class T2, int I> class A<T1*, T2, I> { }; // #3template<class T> class A<int, T*, 5> { }; // #4template<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](#temp.spec.partial.match-example-2)*: template<typename T> concept C = requires (T t) { t.f(); };

template<typename T> struct S { }; // #1template<C T> struct S<T> { }; // #2struct 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*]

[3](#temp.spec.partial.match-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3871)

If the template arguments of a partial specialization cannot be deduced
because of the structure of its [*template-parameter-list*](temp.pre#nt:template-parameter-list "13.1 Preamble [temp.pre]") and the [*template-id*](temp.names#nt:template-id "13.3 Names of template specializations [temp.names]"),
the program is ill-formed[.](#temp.spec.partial.match-3.sentence-1)

[*Example [3](#temp.spec.partial.match-example-3)*: template <int I, int J> struct A {};template <int I> struct A<I+5, I*2> {}; // errortemplate <int I> struct A<I, I> {}; // OKtemplate <int I, int J, int K> struct B {};template <int I> struct B<I, I*2, 2> {}; // OK â *end example*]

[4](#temp.spec.partial.match-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3888)

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[.](#temp.spec.partial.match-4.sentence-1)

The template arguments of a partial specialization are deduced from the arguments
of the primary template[.](#temp.spec.partial.match-4.sentence-2)

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

[1](#temp.spec.partial.order-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3898)

For two partial specializations,
the first is [*more specialized*](temp.deduct.partial#def:more_specialized "13.10.3.5 Deducing template arguments during partial ordering [temp.deduct.partial]") 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](#temp.func.order "13.7.7.3 Partial ordering of function templates [temp.func.order]"):

- [(1.1)](#temp.spec.partial.order-1.1)

  Each of the two
function templates has the same template parameters
and [associated constraints](temp.constr.decl#def:associated_constraints "13.5.3 Constrained declarations [temp.constr.decl]") as the corresponding partial specialization[.](#temp.spec.partial.order-1.1.sentence-1)

- [(1.2)](#temp.spec.partial.order-1.2)

  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*](temp.names#nt:template-argument-list "13.3 Names of template specializations [temp.names]") of the [*simple-template-id*](temp.names#nt:simple-template-id "13.3 Names of template specializations [temp.names]") of the partial specialization[.](#temp.spec.partial.order-1.2.sentence-1)

[2](#temp.spec.partial.order-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3922)

[*Example [1](#temp.spec.partial.order-example-1)*: template<int I, int J, class T> class X { };template<int I, int J> class X<I, J, int> { }; // #1template<int I> class X<I, I, int> { }; // #2template<int I0, int J0> void f(X<I0, J0, int>); // Atemplate<int I0> void f(X<I0, I0, int>); // Btemplate <auto v> class Y { };template <auto* p> class Y<p> { }; // #3template <auto** pp> class Y<pp> { }; // #4template <auto* p0> void g(Y<p0>); // Ctemplate <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*[.](#temp.spec.partial.order-2.sentence-1)

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[.](#temp.spec.partial.order-2.sentence-2)

â *end example*]

[*Example [2](#temp.spec.partial.order-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> { }; // #1template<D T> class S<T> { }; // #2template<C T> void f(S<T>); // Atemplate<D T> void f(S<T>); // B

The partial specialization #2 is more specialized than #1
because B is more specialized than A[.](#temp.spec.partial.order-2.sentence-3)

â *end example*]

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

[1](#temp.spec.partial.member-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L3973)

The members of the class template partial specialization are
unrelated to the members of the primary template[.](#temp.spec.partial.member-1.sentence-1)

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[.](#temp.spec.partial.member-1.sentence-2)

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[.](#temp.spec.partial.member-1.sentence-3)

[*Example [1](#temp.spec.partial.member-example-1)*: // primary class templatetemplate<class T, int I> struct A {void f();};

// member of primary class templatetemplate<class T, int I> void A<T,I>::f() { }// class template partial specializationtemplate<class T> struct A<T,2> {void f(); void g(); void h();};

// member of class template partial specializationtemplate<class T> void A<T,2>::g() { }// explicit specializationtemplate<> 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*]

[2](#temp.spec.partial.member-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4017)

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.inst "13.9.2 Implicit instantiation"), [[temp.explicit]](temp.explicit "13.9.3 Explicit instantiation")),
a declaration for every member template partial specialization is also
instantiated as part of creating the members of the class template
specialization[.](#temp.spec.partial.member-2.sentence-1)

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[.](#temp.spec.partial.member-2.sentence-2)

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[.](#temp.spec.partial.member-2.sentence-3)

[*Example [2](#temp.spec.partial.member-example-2)*: template<class T> struct A {template<class T2> struct B {}; // #1template<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](#temp.fct) Function templates [[temp.fct]](temp.fct)

#### [13.7.7.1](#temp.fct.general) General [[temp.fct.general]](temp.fct.general)

[1](#temp.fct.general-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4052)

A function template defines an unbounded set of related functions[.](#temp.fct.general-1.sentence-1)

[*Example [1](#temp.fct.general-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*]

[2](#temp.fct.general-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4062)

[*Note [1](#temp.fct.general-note-1)*:

A function template can have the same name as other function templates
and non-template functions ([[dcl.fct]](dcl.fct "9.3.4.6 Functions")) in the same scope[.](#temp.fct.general-2.sentence-1)

â *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[.](#temp.fct.general-2.sentence-2)[115](#footnote-115 "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 ([term.odr.use]) in a program, it must be defined; it will not be implicitly instantiated using the function template definition.")

[115)](#footnote-115)[115)](#footnoteref-115)

That is,
declarations of non-template functions do not merely guide
overload resolution of
function template specializations
with the same name[.](#footnote-115.sentence-1)

If such a non-template function is odr-used ([[basic.def.odr]](basic.def.odr#term.odr.use "6.3 One-definition rule")) in a program, it must be defined;
it will not be implicitly instantiated using the function template definition[.](#footnote-115.sentence-2)

#### [13.7.7.2](#temp.over.link) Function template overloading [[temp.over.link]](temp.over.link)

[1](#temp.over.link-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4084)

It is possible to overload function templates so that two different
function template specializations have the same type[.](#temp.over.link-1.sentence-1)

[*Example [1](#temp.over.link-example-1)*:

// translation unit 1:template<class T>void f(T*);void g(int* p) { f(p); // calls f<int>(int*)}

// translation unit 2:template<class T>void f(T);void h(int* p) { f(p); // calls f<int*>(int*)}

â *end example*]

[2](#temp.over.link-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4112)

Such specializations are distinct functions and do not violate the[one-definition rule](basic.def.odr "6.3 One-definition rule [basic.def.odr]")[.](#temp.over.link-2.sentence-1)

[3](#temp.over.link-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4116)

The signature of a function template
is defined in [[intro.defs]](intro.defs "3 Terms and definitions")[.](#temp.over.link-3.sentence-1)

The names of the template parameters are significant only for establishing
the relationship between the template parameters and the rest of the
signature[.](#temp.over.link-3.sentence-2)

[*Note [1](#temp.over.link-note-1)*:

Two distinct function templates can have identical function return types and
function parameter lists, even if overload resolution alone cannot distinguish
them[.](#temp.over.link-3.sentence-3)

template<class T> void f();template<int I> void f(); // OK, overloads the first template// distinguishable with an explicit template argument list â *end note*]

[4](#temp.over.link-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4134)

When an expression that references a template parameter is used in the
function parameter list or the return type in the declaration of a
function template, the expression that references the template
parameter is part of the signature of the function template[.](#temp.over.link-4.sentence-1)

This is
necessary to permit a declaration of a function template in one
translation unit to be linked with another declaration of the function
template in another translation unit and, conversely, to ensure that
function templates that are intended to be distinct are not linked
with one another[.](#temp.over.link-4.sentence-2)

[*Example [2](#temp.over.link-example-2)*: template <int I, int J> A<I+J> f(A<I>, A<J>); // #1template <int K, int L> A<K+L> f(A<K>, A<L>); // same as #1template <int I, int J> A<I-J> f(A<I>, A<J>); // different from #1 â *end example*]

[*Note [2](#temp.over.link-note-2)*:

Most expressions that use template parameters use constant template
parameters, but it is possible for an expression to reference a type
parameter[.](#temp.over.link-4.sentence-3)

For example, a template type parameter can be used in thesizeof operator[.](#temp.over.link-4.sentence-4)

â *end note*]

[5](#temp.over.link-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4160)

Two expressions involving template parameters are considered[*equivalent*](#def:equivalent,expressions "13.7.7.2 Function template overloading [temp.over.link]") if two function definitions containing the expressions would satisfy
the [one-definition rule](basic.def.odr "6.3 One-definition rule [basic.def.odr]"), except that the tokens used
to name the template parameters may differ as long as a token used to
name a template parameter in one expression is replaced by another token
that names the same template parameter in the other expression[.](#temp.over.link-5.sentence-1)

Two unevaluated operands that do not involve template parameters
are considered equivalent
if two function definitions containing the expressions
would satisfy the one-definition rule,
except that the tokens used to name types and declarations may differ
as long as they name the same entities, and
the tokens used to form concept-ids ([[temp.names]](temp.names "13.3 Names of template specializations")) may differ
as long as the two [*template-id*](temp.names#nt:template-id "13.3 Names of template specializations [temp.names]")*s* are the same ([[temp.type]](temp.type "13.6 Type equivalence"))[.](#temp.over.link-5.sentence-2)

[*Note [3](#temp.over.link-note-3)*:

For instance, A<42> and A<40+2> name the same type[.](#temp.over.link-5.sentence-3)

â *end note*]

Two [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]")*s* are never considered equivalent[.](#temp.over.link-5.sentence-4)

[*Note [4](#temp.over.link-note-4)*:

The intent is to avoid [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]")*s* appearing in the
signature of a function template with external linkage[.](#temp.over.link-5.sentence-5)

â *end note*]

For determining whether two dependent names ([[temp.dep]](temp.dep "13.8.3 Dependent names")) are equivalent,
only the name itself is considered, not the result of name lookup[.](#temp.over.link-5.sentence-6)

[*Note [5](#temp.over.link-note-5)*:

If such a dependent name is unqualified,
it is looked up from
a first declaration of the function template ([[temp.res.general]](temp.res.general "13.8.1 General"))[.](#temp.over.link-5.sentence-7)

â *end note*]

[*Example [3](#temp.over.link-example-3)*: template <int I, int J> void f(A<I+J>); // #1template <int K, int L> void f(A<K+L>); // same as #1template <class T> decltype(g(T())) h();int g(int);template <class T> decltype(g(T())) h() // redeclaration of h() uses the earlier lookup…{ return g(T()); } // … although the lookup here does find g(int)int i = h<int>(); // template argument substitution fails; g(int)// not considered at the first declaration of h()// ill-formed, no diagnostic required: the two expressions are functionally equivalent but not equivalenttemplate <int N> void foo(const char (*s)[([]{}, N)]);template <int N> void foo(const char (*s)[([]{}, N)]);

// two different declarations because the non-dependent portions are not considered equivalenttemplate <class T> void spam(decltype([]{}) (*s)[sizeof(T)]);template <class T> void spam(decltype([]{}) (*s)[sizeof(T)]); â *end example*]

Two potentially-evaluated expressions involving template parameters that are not equivalent are[*functionally equivalent*](#def:functionally_equivalent,expressions "13.7.7.2 Function template overloading [temp.over.link]") if, for any given set of template arguments, the evaluation of the
expression results in the same value[.](#temp.over.link-5.sentence-8)

Two unevaluated operands that are not equivalent
are functionally equivalent if, for any given set of template arguments,
the expressions perform
the same operations in the same order with the same entities[.](#temp.over.link-5.sentence-9)

[*Note [6](#temp.over.link-note-6)*:

For instance, one could have redundant parentheses[.](#temp.over.link-5.sentence-10)

â *end note*]

[*Example [4](#temp.over.link-example-4)*: template<int I> concept C = true;template<typename T> struct A {void f() requires C<42>; // #1void f() requires true; // OK, different functions}; â *end example*]

[6](#temp.over.link-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4235)

Two [*template-head*](temp.pre#nt:template-head "13.1 Preamble [temp.pre]")*s* are[*equivalent*](#def:equivalent,template-heads "13.7.7.2 Function template overloading [temp.over.link]") if
their [*template-parameter-list*](temp.pre#nt:template-parameter-list "13.1 Preamble [temp.pre]")*s* have the same length,
corresponding [*template-parameter*](temp.param#nt:template-parameter "13.2 Template parameters [temp.param]")*s* are equivalent
and are both declared with [*type-constraint*](temp.param#nt:type-constraint "13.2 Template parameters [temp.param]")*s* that are equivalent
if either [*template-parameter*](temp.param#nt:template-parameter "13.2 Template parameters [temp.param]") is declared with a [*type-constraint*](temp.param#nt:type-constraint "13.2 Template parameters [temp.param]"),
and if either [*template-head*](temp.pre#nt:template-head "13.1 Preamble [temp.pre]") has a [*requires-clause*](temp.pre#nt:requires-clause "13.1 Preamble [temp.pre]"),
they both have[*requires-clause*](temp.pre#nt:requires-clause "13.1 Preamble [temp.pre]")*s* and the corresponding[*constraint-expression*](temp.constr.decl#nt:constraint-expression "13.5.3 Constrained declarations [temp.constr.decl]")*s* are equivalent[.](#temp.over.link-6.sentence-1)

Two [*template-parameter*](temp.param#nt:template-parameter "13.2 Template parameters [temp.param]")*s* are[*equivalent*](#def:equivalent,template-parameters "13.7.7.2 Function template overloading [temp.over.link]") under the following conditions:

- [(6.1)](#temp.over.link-6.1)

they declare template parameters of the same kind,

- [(6.2)](#temp.over.link-6.2)

if either declares a template parameter pack, they both do,

- [(6.3)](#temp.over.link-6.3)

if they declare constant template parameters,
they have equivalent types
ignoring the use of [*type-constraint*](temp.param#nt:type-constraint "13.2 Template parameters [temp.param]")*s* for placeholder types, and

- [(6.4)](#temp.over.link-6.4)

if they declare template template parameters,
their [*template-head*](temp.pre#nt:template-head "13.1 Preamble [temp.pre]")*s* are equivalent[.](#temp.over.link-6.sentence-2)

When determining whether types or [*type-constraint*](temp.param#nt:type-constraint "13.2 Template parameters [temp.param]")*s* are equivalent, the rules above are used to compare expressions
involving template parameters[.](#temp.over.link-6.sentence-3)

Two [*template-head*](temp.pre#nt:template-head "13.1 Preamble [temp.pre]")*s* are[*functionally equivalent*](#def:functionally_equivalent,template-heads "13.7.7.2 Function template overloading [temp.over.link]") if they accept and are satisfied by ([[temp.constr.constr]](temp.constr.constr "13.5.2 Constraints"))
the same set of template argument lists[.](#temp.over.link-6.sentence-4)

[7](#temp.over.link-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4267)

If the validity or meaning of the program depends on
whether two constructs are equivalent, and they are
functionally equivalent but not equivalent, the program is ill-formed,
no diagnostic required[.](#temp.over.link-7.sentence-1)

Furthermore, if two declarations A and B of function templates

- [(7.1)](#temp.over.link-7.1)

introduce the same name,

- [(7.2)](#temp.over.link-7.2)

have corresponding signatures ([[basic.scope.scope]](basic.scope.scope "6.4.1 General")),

- [(7.3)](#temp.over.link-7.3)

would declare the same entity,
when considering A and B to correspond in that determination ([[basic.link]](basic.link "6.7 Program and linkage")), and

- [(7.4)](#temp.over.link-7.4)

accept and are satisfied by the same set of template argument lists,

but do not correspond,
the program is ill-formed, no diagnostic required[.](#temp.over.link-7.sentence-2)

[8](#temp.over.link-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4287)

[*Note [7](#temp.over.link-note-7)*:

This rule guarantees that equivalent declarations will be linked with
one another, while not requiring implementations to use heroic efforts
to guarantee that functionally equivalent declarations will be treated
as distinct[.](#temp.over.link-8.sentence-1)

For example, the last two declarations are functionally
equivalent and would cause a program to be ill-formed:// guaranteed to be the sametemplate <int I> void f(A<I>, A<I+10>);template <int I> void f(A<I>, A<I+10>);

// guaranteed to be differenttemplate <int I> void f(A<I>, A<I+10>);template <int I> void f(A<I>, A<I+11>);

// ill-formed, no diagnostic requiredtemplate <int I> void f(A<I>, A<I+10>);template <int I> void f(A<I>, A<I+1+2+3+4>);

â *end note*]

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

[1](#temp.func.order-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4312)

If multiple function templates share a name,
the use of that name can be ambiguous because
template argument deduction ([[temp.deduct]](temp.deduct "13.10.3 Template argument deduction")) may identify
a specialization for more than one function template[.](#temp.func.order-1.sentence-1)

[*Partial ordering*](#def:template,function,partial_ordering "13.7.7.3 Partial ordering of function templates [temp.func.order]") of overloaded function template declarations is used in the following contexts
to select the function template to which a function template specialization
refers:

- [(1.1)](#temp.func.order-1.1)

during overload resolution for a call to a function template specialization ([[over.match.best]](over.match.best "12.2.4 Best viable function"));

- [(1.2)](#temp.func.order-1.2)

when the address of a function template specialization is taken;

- [(1.3)](#temp.func.order-1.3)

when a placement operator delete that is a
function template
specialization
is selected to match a placement operator new ([[basic.stc.dynamic.deallocation]](basic.stc.dynamic.deallocation "6.8.6.5.3 Deallocation functions"), [[expr.new]](expr.new "7.6.2.8 New"));

- [(1.4)](#temp.func.order-1.4)

when a [friend function declaration](#temp.friend "13.7.5 Friends [temp.friend]"), an[explicit instantiation](temp.explicit "13.9.3 Explicit instantiation [temp.explicit]") or an [explicit specialization](temp.expl.spec "13.9.4 Explicit specialization [temp.expl.spec]") refers to
a function template specialization[.](#temp.func.order-1.sentence-2)

[2](#temp.func.order-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4339)

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[.](#temp.func.order-2.sentence-1)

The deduction process determines whether
one of the templates is more specialized than the other[.](#temp.func.order-2.sentence-2)

If so, the
more specialized template is the one chosen by the partial ordering
process[.](#temp.func.order-2.sentence-3)

If both deductions succeed, the partial ordering selects
the more constrained template (if one exists) as determined below[.](#temp.func.order-2.sentence-4)

[3](#temp.func.order-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4351)

To produce the transformed template, for each
type, constant,
type template, variable template, or concept
template parameter (including template parameter packs ([[temp.variadic]](#temp.variadic "13.7.4 Variadic templates"))
thereof) synthesize a unique type, value, class template,
variable template, or concept,
respectively, and substitute it for each occurrence of that parameter
in the function type of the template[.](#temp.func.order-3.sentence-1)

[*Note [1](#temp.func.order-note-1)*:

The type replacing the placeholder
in the type of the value synthesized for a constant template parameter
is also a unique synthesized type[.](#temp.func.order-3.sentence-2)

â *end note*]

[4](#temp.func.order-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4369)

A synthesized template has the same [*template-head*](temp.pre#nt:template-head "13.1 Preamble [temp.pre]") as
its corresponding template template parameter[.](#temp.func.order-4.sentence-1)

[5](#temp.func.order-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4375)

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[.](#temp.func.order-5.sentence-1)

If exactly one of the function templates was considered by overload resolution
via a rewritten candidate ([[over.match.oper]](over.match.oper "12.2.2.3 Operators in expressions"))
with a reversed order of parameters,
then the order of the function parameters in its transformed template
is reversed[.](#temp.func.order-5.sentence-2)

For a function template M with cv-qualifiers cv that is a member of a class A:

- [(5.1)](#temp.func.order-5.1)

  The type X(M) is ârvalue reference to cv Aâ
if the optional [*ref-qualifier*](dcl.decl.general#nt:ref-qualifier "9.3.1 General [dcl.decl.general]") ofM is && or
if M has no [*ref-qualifier*](dcl.decl.general#nt:ref-qualifier "9.3.1 General [dcl.decl.general]") 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[.](#temp.func.order-5.1.sentence-1)

- [(5.2)](#temp.func.order-5.2)

  Otherwise, X(M) is âlvalue reference to cv Aâ[.](#temp.func.order-5.2.sentence-1)

[*Note [2](#temp.func.order-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[.](#temp.func.order-5.sentence-4)

â *end note*]

[*Example [1](#temp.func.order-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&); // #1aint main() { A a;
 B<A> b;
 b * a; // calls #1} â *end example*]

[6](#temp.func.order-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4428)

Using the transformed function template's function type,
perform type deduction against the other template as described in [[temp.deduct.partial]](temp.deduct.partial "13.10.3.5 Deducing template arguments during partial ordering")[.](#temp.func.order-6.sentence-1)

[*Example [2](#temp.func.order-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*]

[7](#temp.func.order-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4459)

[*Note [3](#temp.func.order-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)[.](#temp.func.order-7.sentence-1)

[*Example [3](#temp.func.order-example-3)*: template<class T> void f(T); // #1template<class T> void f(T*, int=1); // #2template<class T> void g(T); // #3template<class T> void g(T*, ...); // #4int main() {int* ip;
 f(ip); // calls #2 g(ip); // calls #4} â *end example*]

[*Example [4](#temp.func.order-example-4)*: template<class T, class U> struct A { };

template<class T, class U> void f(U, A<U, T>* p = 0); // #1template< class U> void f(U, A<U, U>* p = 0); // #2template<class T > void g(T, T = T()); // #3template<class T, class... U> void g(T, U ...); // #4void h() { f<int>(42, (A<int, int>*)0); // calls #2 f<int>(42); // error: ambiguous g(42); // error: ambiguous} â *end example*]

[*Example [5](#temp.func.order-example-5)*: template<class T, class... U> void f(T, U...); // #1template<class T > void f(T); // #2template<class T, class... U> void g(T*, U...); // #3template<class T > void g(T); // #4void h(int i) { f(&i); // OK, calls #2 g(&i); // OK, calls #3} â *end example*]

â *end note*]

[8](#temp.func.order-8)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4512)

If deduction against the other template succeeds for both transformed templates,
constraints can be considered as follows:

- [(8.1)](#temp.func.order-8.1)

  If their [*template-parameter-list*](temp.pre#nt:template-parameter-list "13.1 Preamble [temp.pre]")*s* (possibly including [*template-parameter*](temp.param#nt:template-parameter "13.2 Template parameters [temp.param]")*s* invented for an abbreviated function template ([[dcl.fct]](dcl.fct "9.3.4.6 Functions"))) or
function parameter lists differ in length,
neither template is more specialized than the other[.](#temp.func.order-8.1.sentence-1)

- [(8.2)](#temp.func.order-8.2)

  Otherwise:
  * [(8.2.1)](#temp.func.order-8.2.1)

If exactly one of the templates was considered by overload resolution
via a rewritten candidate with reversed order of parameters:
    +
          [(8.2.1.1)](#temp.func.order-8.2.1.1)
If, for either template, some of the template parameters
are not deducible from their function parameters,
neither template is more specialized than the other.

    +
          [(8.2.1.2)](#temp.func.order-8.2.1.2)
If there is either no reordering or more than one reordering
of the associated [*template-parameter-list*](temp.pre#nt:template-parameter-list "13.1 Preamble [temp.pre]") such that
      - [(8.2.1.2.1)](#temp.func.order-8.2.1.2.1)

the corresponding [*template-parameter*](temp.param#nt:template-parameter "13.2 Template parameters [temp.param]")*s* of the [*template-parameter-list*](temp.pre#nt:template-parameter-list "13.1 Preamble [temp.pre]")*s* are equivalent and

      - [(8.2.1.2.2)](#temp.func.order-8.2.1.2.2)

the function parameters that positionally correspond
between the two templates are of the same type,

neither template is more specialized than the other.

  * [(8.2.2)](#temp.func.order-8.2.2)

Otherwise, if the corresponding [*template-parameter*](temp.param#nt:template-parameter "13.2 Template parameters [temp.param]")*s* of the [*template-parameter-list*](temp.pre#nt:template-parameter-list "13.1 Preamble [temp.pre]")*s* are not equivalent ([[temp.over.link]](#temp.over.link "13.7.7.2 Function template overloading")) 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[.](#temp.func.order-8.2.sentence-1)

- [(8.3)](#temp.func.order-8.3)

  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[.](#temp.func.order-8.3.sentence-1)

- [(8.4)](#temp.func.order-8.4)

  Otherwise,
if one template is more constrained than the other ([[temp.constr.order]](temp.constr.order "13.5.5 Partial ordering by constraints")),
the more constrained template is more specialized than the other[.](#temp.func.order-8.4.sentence-1)

- [(8.5)](#temp.func.order-8.5)

  Otherwise, neither template is more specialized than the other[.](#temp.func.order-8.5.sentence-1)

[*Example [6](#temp.func.order-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](#temp.alias) Alias templates [[temp.alias]](temp.alias)

[1](#temp.alias-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4592)

A [*template-declaration*](temp.pre#nt:template-declaration "13.1 Preamble [temp.pre]") in which the [*declaration*](dcl.pre#nt:declaration "9.1 Preamble [dcl.pre]") is an[*alias-declaration*](dcl.pre#nt:alias-declaration "9.1 Preamble [dcl.pre]") ([[dcl.pre]](dcl.pre "9.1 Preamble")) declares the[*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") to be an [*alias template*](#def:template,alias "13.7.8 Alias templates [temp.alias]")[.](#temp.alias-1.sentence-1)

An alias template is a name for a family of
types[.](#temp.alias-1.sentence-2)

The name of the alias template is a [*template-name*](temp.names#nt:template-name "13.3 Names of template specializations [temp.names]")[.](#temp.alias-1.sentence-3)

[2](#temp.alias-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4599)

A

- [(2.1)](#temp.alias-2.1)

[*template-id*](temp.names#nt:template-id "13.3 Names of template specializations [temp.names]") that is not the operand of a [*reflect-expression*](expr.reflect#nt:reflect-expression "7.6.2.10 The reflection operator [expr.reflect]") or

- [(2.2)](#temp.alias-2.2)

[*splice-specialization-specifier*](basic.splice#nt:splice-specialization-specifier "6.6 Splice specifiers [basic.splice]")

that designates the specialization of
an alias template is equivalent to the associated type obtained by
substitution of its [*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]")*s* for the[*template-parameter*](temp.param#nt:template-parameter "13.2 Template parameters [temp.param]")*s* in the [*defining-type-id*](dcl.name#nt:defining-type-id "9.3.2 Type names [dcl.name]") of
the alias template[.](#temp.alias-2.sentence-1)

Any other [*template-id*](temp.names#nt:template-id "13.3 Names of template specializations [temp.names]") that names a specialization of an alias template is
a [*typedef-name*](dcl.typedef#nt:typedef-name "9.2.4 The typedef specifier [dcl.typedef]") for a type alias[.](#temp.alias-2.sentence-2)

[*Note [1](#temp.alias-note-1)*:

An alias template name is never deduced[.](#temp.alias-2.sentence-3)

â *end note*]

[*Example [1](#temp.alias-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: redefinitiontemplate<template<class> class TT>void f(TT<int>);

f(v); // error: Vec not deducedtemplate<template<class,class> class TT>void g(TT<int, Alloc<int>>);
g(v); // OK, TT = vector â *end example*]

[3](#temp.alias-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4644)

However, if the [*template-id*](temp.names#nt:template-id "13.3 Names of template specializations [temp.names]") is dependent, subsequent template
argument substitution still applies to the [*template-id*](temp.names#nt:template-id "13.3 Names of template specializations [temp.names]")[.](#temp.alias-3.sentence-1)

[*Example [2](#temp.alias-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*]

[4](#temp.alias-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4655)

The [*defining-type-id*](dcl.name#nt:defining-type-id "9.3.2 Type names [dcl.name]") in an alias template declaration shall not refer to
the alias template being declared[.](#temp.alias-4.sentence-1)

The type produced by an alias template
specialization shall not directly or indirectly make use of that specialization[.](#temp.alias-4.sentence-2)

[*Example [3](#temp.alias-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*]

[5](#temp.alias-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4670)

The type of a [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") appearing in an alias template declaration
is different between instantiations of that template,
even when the [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]") is not dependent[.](#temp.alias-5.sentence-1)

[*Example [4](#temp.alias-example-4)*: template <class T>using A = decltype([] { }); // A<int> and A<char> refer to different closure types â *end example*]

### [13.7.9](#temp.concept) Concept definitions [[temp.concept]](temp.concept)

[1](#temp.concept-1)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4684)

A [*concept*](#def:concept "13.7.9 Concept definitions [temp.concept]") is a template
that defines constraints on its template arguments[.](#temp.concept-1.sentence-1)

[concept-definition:](#nt:concept-definition "13.7.9 Concept definitions [temp.concept]")  
concept [*concept-name*](#nt:concept-name "13.7.9 Concept definitions [temp.concept]") [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]")opt = [*constraint-expression*](temp.constr.decl#nt:constraint-expression "13.5.3 Constrained declarations [temp.constr.decl]") ;

[concept-name:](#nt:concept-name "13.7.9 Concept definitions [temp.concept]")  
[*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]")

[2](#temp.concept-2)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4698)

A [*concept-definition*](#nt:concept-definition "13.7.9 Concept definitions [temp.concept]") declares a concept[.](#temp.concept-2.sentence-1)

Its [*identifier*](lex.name#nt:identifier "5.11 Identifiers [lex.name]") becomes a [*concept-name*](#nt:concept-name "13.7.9 Concept definitions [temp.concept]") referring to that concept
within its scope[.](#temp.concept-2.sentence-2)

The optional [*attribute-specifier-seq*](dcl.attr.grammar#nt:attribute-specifier-seq "9.13.1 Attribute syntax and semantics [dcl.attr.grammar]") appertains to the concept[.](#temp.concept-2.sentence-3)

[*Example [1](#temp.concept-example-1)*: template<typename T>concept C = requires(T x) {{ x == x } -> std::[convertible_to](concept.convertible#concept:convertible_to "18.4.4 Concept convertible_­to [concept.convertible]")<bool>;};

template<typename T>requires C<T> // C constrains f1(T) in [*constraint-expression*](temp.constr.decl#nt:constraint-expression "13.5.3 Constrained declarations [temp.constr.decl]") T f1(T x) { return x; }template<C T> // C, as a [*type-constraint*](temp.param#nt:type-constraint "13.2 Template parameters [temp.param]"), constrains f2(T) T f2(T x) { return x; } â *end example*]

[3](#temp.concept-3)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4721)

A [*concept-definition*](#nt:concept-definition "13.7.9 Concept definitions [temp.concept]") shall inhabit a namespace scope ([[basic.scope.namespace]](basic.scope.namespace "6.4.6 Namespace scope"))[.](#temp.concept-3.sentence-1)

[4](#temp.concept-4)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4725)

A concept shall not have [associated constraints](temp.constr.decl#def:associated_constraints "13.5.3 Constrained declarations [temp.constr.decl]")[.](#temp.concept-4.sentence-1)

[5](#temp.concept-5)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4728)

A concept is not instantiated ([[temp.spec]](temp.spec "13.9 Template instantiation and specialization"))[.](#temp.concept-5.sentence-1)

[*Note [1](#temp.concept-note-1)*:

A concept-id ([[temp.names]](temp.names "13.3 Names of template specializations")) is evaluated as an expression[.](#temp.concept-5.sentence-2)

A concept cannot be
explicitly instantiated ([[temp.explicit]](temp.explicit "13.9.3 Explicit instantiation")),
explicitly specialized ([[temp.expl.spec]](temp.expl.spec "13.9.4 Explicit specialization")),
or partially specialized ([[temp.spec.partial]](#temp.spec.partial "13.7.6 Partial specialization"))[.](#temp.concept-5.sentence-3)

â *end note*]

[6](#temp.concept-6)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4738)

The [*constraint-expression*](temp.constr.decl#nt:constraint-expression "13.5.3 Constrained declarations [temp.constr.decl]") of a [*concept-definition*](#nt:concept-definition "13.7.9 Concept definitions [temp.concept]") is an unevaluated operand ([[expr.context]](expr.context "7.2.3 Context dependence"))[.](#temp.concept-6.sentence-1)

[7](#temp.concept-7)

[#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4742)

The first declared template parameter of a concept definition is its[*prototype parameter*](#def:prototype_parameter,concept "13.7.9 Concept definitions [temp.concept]")[.](#temp.concept-7.sentence-1)

A [*type concept*](#def:concept,type "13.7.9 Concept definitions [temp.concept]") is a concept whose prototype parameter
is a type template parameter[.](#temp.concept-7.sentence-2)
