Init
This commit is contained in:
232
cppdraft/temp/over/link.md
Normal file
232
cppdraft/temp/over/link.md
Normal file
@@ -0,0 +1,232 @@
|
||||
[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: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](#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<class T> void f();template<int I> 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 <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](#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 <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[.](#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<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](#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 <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*]
|
||||
Reference in New Issue
Block a user