[temp.fct.spec] # 13 Templates [[temp]](./#temp) ## 13.10 Function template specializations [temp.fct.spec] ### [13.10.1](#general) General [[temp.fct.spec.general]](temp.fct.spec.general) [1](#general-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7526) A function instantiated from a function template is called a function template specialization; so is an explicit specialization of a function template[.](#general-1.sentence-1) Template arguments can be explicitly specified when naming the function template specialization, deduced from the context (e.g., deduced from the function arguments in a call to the function template specialization, see [[temp.deduct]](#temp.deduct "13.10.3 Template argument deduction")), or obtained from default template arguments[.](#general-1.sentence-2) [2](#general-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7535) Each function template specialization instantiated from a template has its own copy of any static variable[.](#general-2.sentence-1) [*Example [1](#general-example-1)*: template void f(T* p) {static T s;}; void g(int a, char* b) { f(&a); // calls f(int*) f(&b); // calls f(char**)} Heref(int*) has a static variables of typeint andf(char**) has a static variables of typechar*[.](#general-2.sentence-2) — *end example*] ### [13.10.2](#temp.arg.explicit) Explicit template argument specification [[temp.arg.explicit]](temp.arg.explicit) [1](#temp.arg.explicit-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7566) Template arguments can be specified when referring to a function template specialization that is not a specialization of a constructor template by qualifying the function template name with the list of[*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]")*s* in the same way as[*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]")*s* are specified in uses of a class template specialization[.](#temp.arg.explicit-1.sentence-1) [*Example [1](#temp.arg.explicit-example-1)*: template void sort(Array& v);void f(Array& cv, Array& ci) { sort(cv); // sort(Array&) sort(ci); // sort(Array&)} andtemplate U convert(V v); void g(double d) {int i = convert(d); // int convert(double)char c = convert(d); // char convert(double)} — *end example*] [2](#temp.arg.explicit-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7595) Template arguments shall not be specified when referring to a specialization of a constructor template ([[class.ctor]](class.ctor "11.4.5 Constructors"), [[class.qual]](class.qual "6.5.5.2 Class members"))[.](#temp.arg.explicit-2.sentence-1) [3](#temp.arg.explicit-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7600) A template argument list may be specified when referring to a specialization of a function template - [(3.1)](#temp.arg.explicit-3.1) when a function is called, - [(3.2)](#temp.arg.explicit-3.2) when the address of a function is taken, when a function initializes a reference to function, or when a pointer to member function is formed, - [(3.3)](#temp.arg.explicit-3.3) in an explicit specialization, - [(3.4)](#temp.arg.explicit-3.4) in an explicit instantiation, or - [(3.5)](#temp.arg.explicit-3.5) in a friend declaration[.](#temp.arg.explicit-3.sentence-1) [4](#temp.arg.explicit-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7617) Trailing template arguments that can be deduced ([[temp.deduct]](#temp.deduct "13.10.3 Template argument deduction")) or obtained from default [*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]")*s* may be omitted from the list of explicit [*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]")*s*[.](#temp.arg.explicit-4.sentence-1) [*Note [1](#temp.arg.explicit-note-1)*: A trailing template parameter pack ([[temp.variadic]](temp.variadic "13.7.4 Variadic templates")) not otherwise deduced will be deduced as an empty sequence of template arguments[.](#temp.arg.explicit-4.sentence-2) — *end note*] If all of the template arguments can be deduced or obtained from default [*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]")*s*, they may all be omitted; in this case, the empty template argument list <> itself may also be omitted[.](#temp.arg.explicit-4.sentence-3) [*Example [2](#temp.arg.explicit-example-2)*: template X f(Y);template X g(Y);void h() {int i = f(5.6); // Y deduced as doubleint j = f(5.6); // error: X cannot be deduced f(f); // Y for outer f deduced as int (*)(bool) f(f); // error: f does not denote a single function template specializationint k = g(5.6); // Y deduced as double; Z deduced as an empty sequence f(g); // Y for outer f deduced as int (*)(bool),// Z deduced as an empty sequence} — *end example*] [5](#temp.arg.explicit-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7646) [*Note [2](#temp.arg.explicit-note-2)*: An empty template argument list can be used to indicate that a given use refers to a specialization of a function template even when a non-template function ([[dcl.fct]](dcl.fct "9.3.4.6 Functions")) is visible that would otherwise be used[.](#temp.arg.explicit-5.sentence-1) For example:template int f(T); // #1int f(int); // #2int k = f(1); // uses #2int l = f<>(1); // uses #1 — *end note*] [6](#temp.arg.explicit-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7660) Template arguments that are present shall be specified in the declaration order of their corresponding template parameters[.](#temp.arg.explicit-6.sentence-1) The template argument list shall not specify more[*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]")*s* than there are corresponding[*template-parameter*](temp.param#nt:template-parameter "13.2 Template parameters [temp.param]")*s* unless one of the [*template-parameter*](temp.param#nt:template-parameter "13.2 Template parameters [temp.param]")*s* declares a template parameter pack[.](#temp.arg.explicit-6.sentence-2) [*Example [3](#temp.arg.explicit-example-3)*: template X f(Y,Z);template void f2();void g() { f("aa",3.0); f("aa",3.0); // Z deduced as double f("aa",3.0); // Y deduced as const char*; Z deduced as double f("aa",3.0); // error: X cannot be deduced f2(); // OK} — *end example*] [7](#temp.arg.explicit-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7683) Implicit conversions ([[conv]](conv "7.3 Standard conversions")) will be performed on a function argument to convert it to the type of the corresponding function parameter if the parameter type contains no template parameters that participate in template argument deduction[.](#temp.arg.explicit-7.sentence-1) [*Note [3](#temp.arg.explicit-note-3)*: Template parameters do not participate in template argument deduction if they are explicitly specified[.](#temp.arg.explicit-7.sentence-2) For example, template void f(T); class Complex { Complex(double);}; void g() { f(1); // OK, means f(Complex(1))} — *end note*] [8](#temp.arg.explicit-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7706) [*Note [4](#temp.arg.explicit-note-4)*: Because the explicit template argument list follows the function template name, and because constructor templates ([[class.ctor]](class.ctor "11.4.5 Constructors")) are named without using a function name ([[class.qual]](class.qual "6.5.5.2 Class members")), there is no way to provide an explicit template argument list for these function templates[.](#temp.arg.explicit-8.sentence-1) — *end note*] [9](#temp.arg.explicit-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7715) Template argument deduction can extend the sequence of template arguments corresponding to a template parameter pack, even when the sequence contains explicitly specified template arguments[.](#temp.arg.explicit-9.sentence-1) [*Example [4](#temp.arg.explicit-example-4)*: template void f(Types ... values); void g() { f(0, 0, 0); // Types deduced as the sequence int*, float*, int} — *end example*] ### [13.10.3](#temp.deduct) Template argument deduction [[temp.deduct]](temp.deduct) #### [13.10.3.1](#temp.deduct.general) General [[temp.deduct.general]](temp.deduct.general) [1](#temp.deduct.general-1) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7733) When a function template specialization is referenced, all of the template arguments shall have values[.](#temp.deduct.general-1.sentence-1) The values can be explicitly specified or, in some cases, be deduced from the use or obtained from default[*template-argument*](temp.names#nt:template-argument "13.3 Names of template specializations [temp.names]")*s*[.](#temp.deduct.general-1.sentence-2) [*Example [1](#temp.deduct.general-example-1)*: void f(Array& cv, Array& ci) { sort(cv); // calls sort(Array&) sort(ci); // calls sort(Array&)} andvoid g(double d) {int i = convert(d); // calls convert(double)int c = convert(d); // calls convert(double)} — *end example*] [2](#temp.deduct.general-2) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7758) When an explicit template argument list is specified, if the given [*template-id*](temp.names#nt:template-id "13.3 Names of template specializations [temp.names]") or[*splice-specialization-specifier*](basic.splice#nt:splice-specialization-specifier "6.6 Splice specifiers [basic.splice]") is not valid ([[temp.names]](temp.names "13.3 Names of template specializations")), type deduction fails[.](#temp.deduct.general-2.sentence-1) Otherwise, the specified template argument values are substituted for the corresponding template parameters as specified below[.](#temp.deduct.general-2.sentence-2) [3](#temp.deduct.general-3) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7766) After this substitution is performed, the function parameter type adjustments described in [[dcl.fct]](dcl.fct "9.3.4.6 Functions") are performed[.](#temp.deduct.general-3.sentence-1) [*Example [2](#temp.deduct.general-example-2)*: A parameter type of “void (const int, int[5])” becomes “void(*)(int,int*)”[.](#temp.deduct.general-3.sentence-2) — *end example*] [*Note [1](#temp.deduct.general-note-1)*: A top-level qualifier in a function parameter declaration does not affect the function type but still affects the type of the function parameter variable within the function[.](#temp.deduct.general-3.sentence-3) — *end note*] [*Example [3](#temp.deduct.general-example-3)*: template void f(T t);template void g(const X x);template void h(Z, Z*); int main() {// #1: function type is f(int), t is non const f(1); // #2: function type is f(int), t is const f(1); // #3: function type is g(int), x is const g(1); // #4: function type is g(int), x is const g(1); // #5: function type is h(int, const int*) h(1,0);} — *end example*] [4](#temp.deduct.general-4) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7803) [*Note [2](#temp.deduct.general-note-2)*: f(1) and f(1) call distinct functions even though both of the functions called have the same function type[.](#temp.deduct.general-4.sentence-1) — *end note*] [5](#temp.deduct.general-5) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7809) The resulting substituted and adjusted function type is used as the type of the function template for template argument deduction[.](#temp.deduct.general-5.sentence-1) If a template argument has not been deduced and its corresponding template parameter has a default argument, the template argument is determined by substituting the template arguments determined for preceding template parameters into the default argument[.](#temp.deduct.general-5.sentence-2) If the substitution results in an invalid type, as described above, type deduction fails[.](#temp.deduct.general-5.sentence-3) [*Example [4](#temp.deduct.general-example-4)*: template void f(T t = 0, U u = 0); void g() { f(1, 'c'); // f(1,'c') f(1); // f(1,0) f(); // error: T cannot be deduced f(); // f(0,0) f(); // f(0,0)} — *end example*] When all template arguments have been deduced or obtained from default template arguments, all uses of template parameters in the template parameter list of the template are replaced with the corresponding deduced or default argument values[.](#temp.deduct.general-5.sentence-4) If the substitution results in an invalid type, as described above, type deduction fails[.](#temp.deduct.general-5.sentence-5) If the function template has associated constraints ([[temp.constr.decl]](temp.constr.decl "13.5.3 Constrained declarations")), those constraints are checked for satisfaction ([[temp.constr.constr]](temp.constr.constr "13.5.2 Constraints"))[.](#temp.deduct.general-5.sentence-6) If the constraints are not satisfied, type deduction fails[.](#temp.deduct.general-5.sentence-7) In the context of a function call, if type deduction has not yet failed, then for those function parameters for which the function call has arguments, each function parameter with a type that was non-dependent before substitution of any explicitly-specified template arguments is checked against its corresponding argument; if the corresponding argument cannot be implicitly converted to the parameter type, type deduction fails[.](#temp.deduct.general-5.sentence-8) [*Note [3](#temp.deduct.general-note-3)*: Overload resolution will check the other parameters, including parameters with dependent types in which no template parameters participate in template argument deduction and parameters that became non-dependent due to substitution of explicitly-specified template arguments[.](#temp.deduct.general-5.sentence-9) — *end note*] If type deduction has not yet failed, then all uses of template parameters in the function type are replaced with the corresponding deduced or default argument values[.](#temp.deduct.general-5.sentence-10) If the substitution results in an invalid type, as described above, type deduction fails[.](#temp.deduct.general-5.sentence-11) [*Example [5](#temp.deduct.general-example-5)*: template struct Z {typedef typename T::x xx;};template concept C = requires { typename T::A; };template typename Z::xx f(void *, T); // #1template void f(int, T); // #2struct A {} a;struct ZZ {template ::xx> operator T *(); operator int();};int main() { ZZ zz; f(1, a); // OK, deduction fails for #1 because there is no conversion from int to void* f(zz, 42); // OK, deduction fails for #1 because C is not satisfied} — *end example*] [6](#temp.deduct.general-6) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7882) At certain points in the template argument deduction process it is necessary to take a function type that makes use of template parameters and replace those template parameters with the corresponding template arguments[.](#temp.deduct.general-6.sentence-1) This is done at the beginning of template argument deduction when any explicitly specified template arguments are substituted into the function type, and again at the end of template argument deduction when any template arguments that were deduced or obtained from default arguments are substituted[.](#temp.deduct.general-6.sentence-2) [7](#temp.deduct.general-7) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7891) The [*deduction substitution loci*](#def:deduction_substitution_loci "13.10.3.1 General [temp.deduct.general]") are - [(7.1)](#temp.deduct.general-7.1) the function type outside of the [*noexcept-specifier*](except.spec#nt:noexcept-specifier "14.5 Exception specifications [except.spec]"), - [(7.2)](#temp.deduct.general-7.2) the [*explicit-specifier*](dcl.fct.spec#nt:explicit-specifier "9.2.3 Function specifiers [dcl.fct.spec]"), - [(7.3)](#temp.deduct.general-7.3) the template parameter declarations, and - [(7.4)](#temp.deduct.general-7.4) the template argument list of a partial specialization ([[temp.spec.partial.general]](temp.spec.partial.general "13.7.6.1 General"))[.](#temp.deduct.general-7.sentence-1) The substitution occurs in all types and expressions that are used in the deduction substitution loci[.](#temp.deduct.general-7.sentence-2) The expressions include not only constant expressions such as those that appear in array bounds or as nontype template arguments but also general expressions (i.e., non-constant expressions) inside sizeof, decltype, and other contexts that allow non-constant expressions[.](#temp.deduct.general-7.sentence-3) The substitution proceeds in lexical order and stops when a condition that causes deduction to fail is encountered[.](#temp.deduct.general-7.sentence-4) If substitution into different declarations of the same function template would cause template instantiations to occur in a different order or not at all, the program is ill-formed; no diagnostic required[.](#temp.deduct.general-7.sentence-5) [*Note [4](#temp.deduct.general-note-4)*: The equivalent substitution in exception specifications ([[except.spec]](except.spec "14.5 Exception specifications")) and function contract assertions ([[dcl.contract.func]](dcl.contract.func "9.4.1 General")) is done only when the [*noexcept-specifier*](except.spec#nt:noexcept-specifier "14.5 Exception specifications [except.spec]") or [*function-contract-specifier*](dcl.contract.func#nt:function-contract-specifier "9.4.1 General [dcl.contract.func]"), respectively, is instantiated, at which point a program is ill-formed if the substitution results in an invalid type or expression[.](#temp.deduct.general-7.sentence-6) — *end note*] [*Example [6](#temp.deduct.general-example-6)*: template struct A { using X = typename T::X; };template typename T::X f(typename A::X);template void f(...) { }template auto g(typename A::X) -> typename T::X;template void g(...) { }template typename T::X h(typename A::X);template auto h(typename A::X) -> typename T::X; // redeclarationtemplate void h(...) { }void x() { f(0); // OK, substituting return type causes deduction to fail g(0); // error, substituting parameter type instantiates A h(0); // ill-formed, no diagnostic required} — *end example*] [8](#temp.deduct.general-8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7941) If a substitution results in an invalid type or expression, type deduction fails[.](#temp.deduct.general-8.sentence-1) An invalid type or expression is one that would be ill-formed, with a diagnostic required, if written in the same context using the substituted arguments[.](#temp.deduct.general-8.sentence-2) [*Note [5](#temp.deduct.general-note-5)*: If no diagnostic is required, the program is still ill-formed[.](#temp.deduct.general-8.sentence-3) Access checking is done as part of the substitution process[.](#temp.deduct.general-8.sentence-4) — *end note*] Invalid types and expressions can result in a deduction failure only in the immediate context of the deduction substitution loci[.](#temp.deduct.general-8.sentence-5) [*Note [6](#temp.deduct.general-note-6)*: The substitution into types and expressions can result in effects such as the instantiation of class template specializations and/or function template specializations, the generation of implicitly-defined functions, etc[.](#temp.deduct.general-8.sentence-6) Such effects are not in the “immediate context” and can result in the program being ill-formed[.](#temp.deduct.general-8.sentence-7) — *end note*] [9](#temp.deduct.general-9) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7959) When substituting into a [*lambda-expression*](expr.prim.lambda.general#nt:lambda-expression "7.5.6.1 General [expr.prim.lambda.general]"), substitution into its body is not in the immediate context[.](#temp.deduct.general-9.sentence-1) [*Note [7](#temp.deduct.general-note-7)*: The intent is to avoid requiring implementations to deal with substitution failure involving arbitrary statements[.](#temp.deduct.general-9.sentence-2) [*Example [7](#temp.deduct.general-example-7)*: template auto f(T) -> decltype([]() { T::invalid; } ());void f(...); f(0); // error: invalid expression not part of the immediate contexttemplate void g(T);void g(...); g(0); // error: invalid expression not part of the immediate contexttemplate auto h(T) -> decltype([x = T::invalid]() { });void h(...); h(0); // error: invalid expression not part of the immediate contexttemplate auto i(T) -> decltype([]() -> typename T::invalid { });void i(...); i(0); // error: invalid expression not part of the immediate contexttemplate auto j(T t) -> decltype([](auto x) -> decltype(x.invalid) { } (t)); // #1void j(...); // #2 j(0); // deduction fails on #1, calls #2 — *end example*] — *end note*] [10](#temp.deduct.general-10) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L7995) [*Example [8](#temp.deduct.general-example-8)*: struct X { };struct Y { Y(X) {}}; template auto f(T t1, T t2) -> decltype(t1 + t2); // #1 X f(Y, Y); // #2 X x1, x2; X x3 = f(x1, x2); // deduction fails on #1 (cannot add X+X), calls #2 — *end example*] [11](#temp.deduct.general-11) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L8011) [*Note [8](#temp.deduct.general-note-8)*: Type deduction can fail for the following reasons: - [(11.1)](#temp.deduct.general-11.1) Attempting to instantiate a pack expansion containing multiple packs of differing lengths[.](#temp.deduct.general-11.1.sentence-1) - [(11.2)](#temp.deduct.general-11.2) Attempting to create an array with an element type that is void, a function type, or a reference type, or attempting to create an array with a size that is zero or negative[.](#temp.deduct.general-11.2.sentence-1) [*Example [9](#temp.deduct.general-example-9)*: template int f(T[5]);int I = f(0);int j = f(0); // invalid array — *end example*] - [(11.3)](#temp.deduct.general-11.3) Attempting to use a type that is not a class or enumeration type in a qualified name[.](#temp.deduct.general-11.3.sentence-1) [*Example [10](#temp.deduct.general-example-10)*: template int f(typename T::B*);int i = f(0); — *end example*] - [(11.4)](#temp.deduct.general-11.4) Attempting to use a type in a [*nested-name-specifier*](expr.prim.id.qual#nt:nested-name-specifier "7.5.5.3 Qualified names [expr.prim.id.qual]") of a[*qualified-id*](expr.prim.id.qual#nt:qualified-id "7.5.5.3 Qualified names [expr.prim.id.qual]") when that type does not contain the specified member, or * [(11.4.1)](#temp.deduct.general-11.4.1) the specified member is not a type where a type is required, or * [(11.4.2)](#temp.deduct.general-11.4.2) the specified member is not a template where a template is required, or * [(11.4.3)](#temp.deduct.general-11.4.3) the specified member is not a non-type, non-template where a non-type, non-template is required[.](#temp.deduct.general-11.4.sentence-1) [*Example [11](#temp.deduct.general-example-11)*: template struct X { };template