From Jason Turner

[temp.fct]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmp7h_vmsxx/{from.md → to.md} +88 -30
tmp/tmp7h_vmsxx/{from.md → to.md} RENAMED
@@ -1,15 +1,20 @@
1
  ### Function templates <a id="temp.fct">[[temp.fct]]</a>
2
 
3
- A function template defines an unbounded set of related functions. a
4
- family of sort functions might be declared like this:
 
 
 
5
 
6
  ``` cpp
7
  template<class T> class Array { };
8
  template<class T> void sort(Array<T>&);
9
  ```
10
 
 
 
11
  A function template can be overloaded with other function templates and
12
  with non-template functions ([[dcl.fct]]). A non-template function is
13
  not related to a function template (i.e., it is never considered to be a
14
  specialization), even if it has the same name and type as a potentially
15
  generated function template specialization.[^5]
@@ -17,76 +22,92 @@ generated function template specialization.[^5]
17
  #### Function template overloading <a id="temp.over.link">[[temp.over.link]]</a>
18
 
19
  It is possible to overload function templates so that two different
20
  function template specializations have the same type.
21
 
 
 
22
  ``` cpp
23
- // file1.c
24
  template<class T>
25
  void f(T*);
26
  void g(int* p) {
27
  f(p); // calls f<int>(int*)
28
  }
29
  ```
30
 
31
  ``` cpp
32
- // file2.c
33
  template<class T>
34
  void f(T);
35
  void h(int* p) {
36
  f(p); // calls f<int*>(int*)
37
  }
38
  ```
39
 
40
- Such specializations are distinct functions and do not violate the one
41
- definition rule ([[basic.def.odr]]).
42
-
43
- The signature of a function template is defined in  [[intro.defs]]. The
44
- names of the template parameters are significant only for establishing
45
- the relationship between the template parameters and the rest of the
46
- signature. Two distinct function templates may have identical function
47
- return types and function parameter lists, even if overload resolution
48
- alone cannot distinguish them.
 
 
 
 
 
 
49
 
50
  ``` cpp
51
  template<class T> void f();
52
  template<int I> void f(); // OK: overloads the first template
53
  // distinguishable with an explicit template argument list
54
  ```
55
 
 
 
56
  When an expression that references a template parameter is used in the
57
  function parameter list or the return type in the declaration of a
58
  function template, the expression that references the template parameter
59
  is part of the signature of the function template. This is necessary to
60
  permit a declaration of a function template in one translation unit to
61
  be linked with another declaration of the function template in another
62
  translation unit and, conversely, to ensure that function templates that
63
  are intended to be distinct are not linked with one another.
64
 
 
 
65
  ``` cpp
66
  template <int I, int J> A<I+J> f(A<I>, A<J>); // #1
67
  template <int K, int L> A<K+L> f(A<K>, A<L>); // same as #1
68
  template <int I, int J> A<I-J> f(A<I>, A<J>); // different from #1
69
  ```
70
 
71
- Most expressions that use template parameters use non-type template
72
- parameters, but it is possible for an expression to reference a type
73
- parameter. For example, a template type parameter can be used in the
74
- `sizeof` operator.
 
 
75
 
76
  Two expressions involving template parameters are considered
77
  *equivalent* if two function definitions containing the expressions
78
- would satisfy the one definition rule ([[basic.def.odr]]), except that
79
  the tokens used to name the template parameters may differ as long as a
80
  token used to name a template parameter in one expression is replaced by
81
  another token that names the same template parameter in the other
82
  expression. For determining whether two dependent names ([[temp.dep]])
83
  are equivalent, only the name itself is considered, not the result of
84
  name lookup in the context of the template. If multiple declarations of
85
  the same function template differ in the result of this name lookup, the
86
  result for the first declaration is used.
87
 
 
 
88
  ``` cpp
89
  template <int I, int J> void f(A<I+J>); // #1
90
  template <int K, int L> void f(A<K+L>); // same as #1
91
 
92
  template <class T> decltype(g(T())) h();
@@ -95,10 +116,12 @@ template <class T> decltype(g(T())) h() // redeclaration of h() uses the
95
  { return g(T()); } // ...although the lookup here does find g(int)
96
  int i = h<int>(); // template argument substitution fails; g(int)
97
  // was not in scope at the first declaration of h()
98
  ```
99
 
 
 
100
  Two expressions involving template parameters that are not equivalent
101
  are *functionally equivalent* if, for any given set of template
102
  arguments, the evaluation of the expression results in the same value.
103
 
104
  Two function templates are *equivalent* if they are declared in the same
@@ -109,11 +132,13 @@ parameters. Two function templates are *functionally equivalent* if they
109
  are equivalent except that one or more expressions that involve template
110
  parameters in the return types and parameter lists are functionally
111
  equivalent using the rules described above to compare expressions
112
  involving template parameters. If a program contains declarations of
113
  function templates that are functionally equivalent but not equivalent,
114
- the program is ill-formed; no diagnostic is required.
 
 
115
 
116
  This rule guarantees that equivalent declarations will be linked with
117
  one another, while not requiring implementations to use heroic efforts
118
  to guarantee that functionally equivalent declarations will be treated
119
  as distinct. For example, the last two declarations are functionally
@@ -131,10 +156,12 @@ template <int I> void f(A<I>, A<I+11>);
131
  // Ill-formed, no diagnostic required
132
  template <int I> void f(A<I>, A<I+10>);
133
  template <int I> void f(A<I>, A<I+1+2+3+4>);
134
  ```
135
 
 
 
136
  #### Partial ordering of function templates <a id="temp.func.order">[[temp.func.order]]</a>
137
 
138
  If a function template is overloaded, the use of a function template
139
  specialization might be ambiguous because template argument deduction (
140
  [[temp.deduct]]) may associate the function template specialization with
@@ -162,20 +189,29 @@ specialized template is the one chosen by the partial ordering process.
162
 
163
  To produce the transformed template, for each type, non-type, or
164
  template template parameter (including template parameter packs (
165
  [[temp.variadic]]) thereof) synthesize a unique type, value, or class
166
  template respectively and substitute it for each occurrence of that
167
- parameter in the function type of the template. If only one of the
168
- function templates is a non-static member of some class `A`, that
169
- function template is considered to have a new first parameter inserted
170
- in its function parameter list. Given cv as the cv-qualifiers of the
171
- function template (if any), the new parameter is of type “rvalue
172
- reference to cv `A`” if the optional *ref-qualifier* of the function
173
- template is `&&`, or of type “lvalue reference to cv `A`” otherwise.
174
- This allows a non-static member to be ordered with respect to a
175
- nonmember function and for the results to be equivalent to the ordering
176
- of two equivalent nonmembers.
 
 
 
 
 
 
 
 
 
177
 
178
  ``` cpp
179
  struct A { };
180
  template<class T> struct B {
181
  template<class R> int operator*(R&); // #1
@@ -191,14 +227,18 @@ int main() {
191
  B<A> b;
192
  b * a; // calls #1a
193
  }
194
  ```
195
 
 
 
196
  Using the transformed function template’s function type, perform type
197
  deduction against the other template as described in 
198
  [[temp.deduct.partial]].
199
 
 
 
200
  ``` cpp
201
  template<class T> struct A { A(); };
202
 
203
  template<class T> void f(T);
204
  template<class T> void f(T*);
@@ -212,23 +252,29 @@ template<class T> void h(A<T>&);
212
 
213
  void m() {
214
  const int* p;
215
  f(p); // f(const T*) is more specialized than f(T) or f(T*)
216
  float x;
217
- g(x); // Ambiguous: g(T) or g(T&)
218
  A<int> z;
219
  h(z); // overload resolution selects h(A<T>&)
220
  const A<int> z2;
221
  h(z2); // h(const T&) is called because h(A<T>&) is not callable
222
  }
223
  ```
224
 
 
 
 
 
225
  Since partial ordering in a call context considers only parameters for
226
  which there are explicit call arguments, some parameters are ignored
227
  (namely, function parameter packs, parameters with default arguments,
228
  and ellipsis parameters).
229
 
 
 
230
  ``` cpp
231
  template<class T> void f(T); // #1
232
  template<class T> void f(T*, int=1); // #2
233
  template<class T> void g(T); // #3
234
  template<class T> void g(T*, ...); // #4
@@ -240,10 +286,14 @@ int main() {
240
  f(ip); // calls #2
241
  g(ip); // calls #4
242
  }
243
  ```
244
 
 
 
 
 
245
  ``` cpp
246
  template<class T, class U> struct A { };
247
 
248
  template<class T, class U> void f(U, A<U, T>* p = 0); // #1
249
  template< class U> void f(U, A<U, U>* p = 0); // #2
@@ -255,10 +305,14 @@ void h() {
255
  f<int>(42); // error: ambiguous
256
  g(42); // error: ambiguous
257
  }
258
  ```
259
 
 
 
 
 
260
  ``` cpp
261
  template<class T, class... U> void f(T, U...); // #1
262
  template<class T > void f(T); // #2
263
  template<class T, class... U> void g(T*, U...); // #3
264
  template<class T > void g(T); // #4
@@ -267,5 +321,9 @@ void h(int i) {
267
  f(&i); // error: ambiguous
268
  g(&i); // OK: calls #3
269
  }
270
  ```
271
 
 
 
 
 
 
1
  ### Function templates <a id="temp.fct">[[temp.fct]]</a>
2
 
3
+ A function template defines an unbounded set of related functions.
4
+
5
+ [*Example 1*:
6
+
7
+ A family of sort functions might be declared like this:
8
 
9
  ``` cpp
10
  template<class T> class Array { };
11
  template<class T> void sort(Array<T>&);
12
  ```
13
 
14
+ — *end example*]
15
+
16
  A function template can be overloaded with other function templates and
17
  with non-template functions ([[dcl.fct]]). A non-template function is
18
  not related to a function template (i.e., it is never considered to be a
19
  specialization), even if it has the same name and type as a potentially
20
  generated function template specialization.[^5]
 
22
  #### Function template overloading <a id="temp.over.link">[[temp.over.link]]</a>
23
 
24
  It is possible to overload function templates so that two different
25
  function template specializations have the same type.
26
 
27
+ [*Example 1*:
28
+
29
  ``` cpp
30
+ // translation unit 1:
31
  template<class T>
32
  void f(T*);
33
  void g(int* p) {
34
  f(p); // calls f<int>(int*)
35
  }
36
  ```
37
 
38
  ``` cpp
39
+ // translation unit 2:
40
  template<class T>
41
  void f(T);
42
  void h(int* p) {
43
  f(p); // calls f<int*>(int*)
44
  }
45
  ```
46
 
47
+ *end example*]
48
+
49
+ Such specializations are distinct functions and do not violate the
50
+ one-definition rule ([[basic.def.odr]]).
51
+
52
+ The signature of a function template is defined in Clause 
53
+ [[intro.defs]]. The names of the template parameters are significant
54
+ only for establishing the relationship between the template parameters
55
+ and the rest of the signature.
56
+
57
+ [*Note 1*:
58
+
59
+ Two distinct function templates may have identical function return types
60
+ and function parameter lists, even if overload resolution alone cannot
61
+ distinguish them.
62
 
63
  ``` cpp
64
  template<class T> void f();
65
  template<int I> void f(); // OK: overloads the first template
66
  // distinguishable with an explicit template argument list
67
  ```
68
 
69
+ — *end note*]
70
+
71
  When an expression that references a template parameter is used in the
72
  function parameter list or the return type in the declaration of a
73
  function template, the expression that references the template parameter
74
  is part of the signature of the function template. This is necessary to
75
  permit a declaration of a function template in one translation unit to
76
  be linked with another declaration of the function template in another
77
  translation unit and, conversely, to ensure that function templates that
78
  are intended to be distinct are not linked with one another.
79
 
80
+ [*Example 2*:
81
+
82
  ``` cpp
83
  template <int I, int J> A<I+J> f(A<I>, A<J>); // #1
84
  template <int K, int L> A<K+L> f(A<K>, A<L>); // same as #1
85
  template <int I, int J> A<I-J> f(A<I>, A<J>); // different from #1
86
  ```
87
 
88
+ *end example*]
89
+
90
+ [*Note 2*: Most expressions that use template parameters use non-type
91
+ template parameters, but it is possible for an expression to reference a
92
+ type parameter. For example, a template type parameter can be used in
93
+ the `sizeof` operator. — *end note*]
94
 
95
  Two expressions involving template parameters are considered
96
  *equivalent* if two function definitions containing the expressions
97
+ would satisfy the one-definition rule ([[basic.def.odr]]), except that
98
  the tokens used to name the template parameters may differ as long as a
99
  token used to name a template parameter in one expression is replaced by
100
  another token that names the same template parameter in the other
101
  expression. For determining whether two dependent names ([[temp.dep]])
102
  are equivalent, only the name itself is considered, not the result of
103
  name lookup in the context of the template. If multiple declarations of
104
  the same function template differ in the result of this name lookup, the
105
  result for the first declaration is used.
106
 
107
+ [*Example 3*:
108
+
109
  ``` cpp
110
  template <int I, int J> void f(A<I+J>); // #1
111
  template <int K, int L> void f(A<K+L>); // same as #1
112
 
113
  template <class T> decltype(g(T())) h();
 
116
  { return g(T()); } // ...although the lookup here does find g(int)
117
  int i = h<int>(); // template argument substitution fails; g(int)
118
  // was not in scope at the first declaration of h()
119
  ```
120
 
121
+ — *end example*]
122
+
123
  Two expressions involving template parameters that are not equivalent
124
  are *functionally equivalent* if, for any given set of template
125
  arguments, the evaluation of the expression results in the same value.
126
 
127
  Two function templates are *equivalent* if they are declared in the same
 
132
  are equivalent except that one or more expressions that involve template
133
  parameters in the return types and parameter lists are functionally
134
  equivalent using the rules described above to compare expressions
135
  involving template parameters. If a program contains declarations of
136
  function templates that are functionally equivalent but not equivalent,
137
+ the program is ill-formed, no diagnostic required.
138
+
139
+ [*Note 3*:
140
 
141
  This rule guarantees that equivalent declarations will be linked with
142
  one another, while not requiring implementations to use heroic efforts
143
  to guarantee that functionally equivalent declarations will be treated
144
  as distinct. For example, the last two declarations are functionally
 
156
  // Ill-formed, no diagnostic required
157
  template <int I> void f(A<I>, A<I+10>);
158
  template <int I> void f(A<I>, A<I+1+2+3+4>);
159
  ```
160
 
161
+ — *end note*]
162
+
163
  #### Partial ordering of function templates <a id="temp.func.order">[[temp.func.order]]</a>
164
 
165
  If a function template is overloaded, the use of a function template
166
  specialization might be ambiguous because template argument deduction (
167
  [[temp.deduct]]) may associate the function template specialization with
 
189
 
190
  To produce the transformed template, for each type, non-type, or
191
  template template parameter (including template parameter packs (
192
  [[temp.variadic]]) thereof) synthesize a unique type, value, or class
193
  template respectively and substitute it for each occurrence of that
194
+ parameter in the function type of the template.
195
+
196
+ [*Note 1*: The type replacing the placeholder in the type of the value
197
+ synthesized for a non-type template parameter is also a unique
198
+ synthesized type. *end note*]
199
+
200
+ If only one of the function templates *M* is a non-static member of some
201
+ class *A*, *M* is considered to have a new first parameter inserted in
202
+ its function parameter list. Given cv as the cv-qualifiers of *M* (if
203
+ any), the new parameter is of type “rvalue reference to cv *A*” if the
204
+ optional *ref-qualifier* of *M* is `&&` or if *M* has no *ref-qualifier*
205
+ and the first parameter of the other template has rvalue reference type.
206
+ Otherwise, the new parameter is of type “lvalue reference to cv *A*”.
207
+
208
+ [*Note 2*: This allows a non-static member to be ordered with respect
209
+ to a non-member function and for the results to be equivalent to the
210
+ ordering of two equivalent non-members. — *end note*]
211
+
212
+ [*Example 1*:
213
 
214
  ``` cpp
215
  struct A { };
216
  template<class T> struct B {
217
  template<class R> int operator*(R&); // #1
 
227
  B<A> b;
228
  b * a; // calls #1a
229
  }
230
  ```
231
 
232
+ — *end example*]
233
+
234
  Using the transformed function template’s function type, perform type
235
  deduction against the other template as described in 
236
  [[temp.deduct.partial]].
237
 
238
+ [*Example 2*:
239
+
240
  ``` cpp
241
  template<class T> struct A { A(); };
242
 
243
  template<class T> void f(T);
244
  template<class T> void f(T*);
 
252
 
253
  void m() {
254
  const int* p;
255
  f(p); // f(const T*) is more specialized than f(T) or f(T*)
256
  float x;
257
+ g(x); // ambiguous: g(T) or g(T&)
258
  A<int> z;
259
  h(z); // overload resolution selects h(A<T>&)
260
  const A<int> z2;
261
  h(z2); // h(const T&) is called because h(A<T>&) is not callable
262
  }
263
  ```
264
 
265
+ — *end example*]
266
+
267
+ [*Note 3*:
268
+
269
  Since partial ordering in a call context considers only parameters for
270
  which there are explicit call arguments, some parameters are ignored
271
  (namely, function parameter packs, parameters with default arguments,
272
  and ellipsis parameters).
273
 
274
+ [*Example 3*:
275
+
276
  ``` cpp
277
  template<class T> void f(T); // #1
278
  template<class T> void f(T*, int=1); // #2
279
  template<class T> void g(T); // #3
280
  template<class T> void g(T*, ...); // #4
 
286
  f(ip); // calls #2
287
  g(ip); // calls #4
288
  }
289
  ```
290
 
291
+ — *end example*]
292
+
293
+ [*Example 4*:
294
+
295
  ``` cpp
296
  template<class T, class U> struct A { };
297
 
298
  template<class T, class U> void f(U, A<U, T>* p = 0); // #1
299
  template< class U> void f(U, A<U, U>* p = 0); // #2
 
305
  f<int>(42); // error: ambiguous
306
  g(42); // error: ambiguous
307
  }
308
  ```
309
 
310
+ — *end example*]
311
+
312
+ [*Example 5*:
313
+
314
  ``` cpp
315
  template<class T, class... U> void f(T, U...); // #1
316
  template<class T > void f(T); // #2
317
  template<class T, class... U> void g(T*, U...); // #3
318
  template<class T > void g(T); // #4
 
321
  f(&i); // error: ambiguous
322
  g(&i); // OK: calls #3
323
  }
324
  ```
325
 
326
+ — *end example*]
327
+
328
+ — *end note*]
329
+