[temp.over.link] # 13 Templates [[temp]](./#temp) ## 13.7 Template declarations [[temp.decls]](temp.decls#temp.over.link) ### 13.7.7 Function templates [[temp.fct]](temp.fct#temp.over.link) #### 13.7.7.2 Function template overloading [temp.over.link] [1](#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[.](#1.sentence-1) [*Example [1](#example-1)*: // translation unit 1:templatevoid f(T*);void g(int* p) { f(p); // calls f(int*)} // translation unit 2:templatevoid f(T);void h(int* p) { f(p); // calls f(int*)} — *end example*] [2](#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]")[.](#2.sentence-1) [3](#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")[.](#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[.](#3.sentence-2) [*Note [1](#note-1)*: Two distinct function templates can have identical function return types and function parameter lists, even if overload resolution alone cannot distinguish them[.](#3.sentence-3) template void f();template void f(); // OK, overloads the first template// distinguishable with an explicit template argument list — *end note*] [4](#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[.](#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[.](#4.sentence-2) [*Example [2](#example-2)*: template A f(A, A); // #1template A f(A, A); // same as #1template A f(A, A); // different from #1 — *end example*] [*Note [2](#note-2)*: Most expressions that use template parameters use constant template parameters, but it is possible for an expression to reference a type parameter[.](#4.sentence-3) For example, a template type parameter can be used in thesizeof operator[.](#4.sentence-4) — *end note*] [5](#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[.](#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"))[.](#5.sentence-2) [*Note [3](#note-3)*: For instance, A<42> and A<40+2> name the same type[.](#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[.](#5.sentence-4) [*Note [4](#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[.](#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[.](#5.sentence-6) [*Note [5](#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"))[.](#5.sentence-7) — *end note*] [*Example [3](#example-3)*: template void f(A); // #1template void f(A); // same as #1template decltype(g(T())) h();int g(int);template 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(); // 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 void foo(const char (*s)[([]{}, N)]);template void foo(const char (*s)[([]{}, N)]); // two different declarations because the non-dependent portions are not considered equivalenttemplate void spam(decltype([]{}) (*s)[sizeof(T)]);template 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[.](#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[.](#5.sentence-9) [*Note [6](#note-6)*: For instance, one could have redundant parentheses[.](#5.sentence-10) — *end note*] [*Example [4](#example-4)*: template concept C = true;template struct A {void f() requires C<42>; // #1void f() requires true; // OK, different functions}; — *end example*] [6](#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[.](#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)](#6.1) they declare template parameters of the same kind, - [(6.2)](#6.2) if either declares a template parameter pack, they both do, - [(6.3)](#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)](#6.4) if they declare template template parameters, their [*template-head*](temp.pre#nt:template-head "13.1 Preamble [temp.pre]")*s* are equivalent[.](#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[.](#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[.](#6.sentence-4) [7](#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[.](#7.sentence-1) Furthermore, if two declarations A and B of function templates - [(7.1)](#7.1) introduce the same name, - [(7.2)](#7.2) have corresponding signatures ([[basic.scope.scope]](basic.scope.scope "6.4.1 General")), - [(7.3)](#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)](#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[.](#7.sentence-2) [8](#8) [#](http://github.com/Eelis/draft/tree/9adde4bc1c62ec234483e63ea3b70a59724c745a/source/templates.tex#L4287) [*Note [7](#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[.](#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 void f(A, A);template void f(A, A); // guaranteed to be differenttemplate void f(A, A);template void f(A, A); // ill-formed, no diagnostic requiredtemplate void f(A, A);template void f(A, A); — *end note*]