- tmp/tmpsv4lou79/{from.md → to.md} +155 -66
tmp/tmpsv4lou79/{from.md → to.md}
RENAMED
|
@@ -1,46 +1,55 @@
|
|
| 1 |
-
### Functions <a id="dcl.fct">[[dcl.fct]]</a>
|
| 2 |
|
| 3 |
In a declaration `T` `D` where `D` has the form
|
| 4 |
|
| 5 |
``` bnf
|
| 6 |
-
'D1 (' parameter-declaration-clause ')' cv-qualifier-seqₒₚₜ
|
| 7 |
ref-qualifierₒₚₜ noexcept-specifierₒₚₜ attribute-specifier-seqₒₚₜ
|
| 8 |
```
|
| 9 |
|
| 10 |
and the type of the contained *declarator-id* in the declaration `T`
|
| 11 |
`D1` is “*derived-declarator-type-list* `T`”, the type of the
|
| 12 |
-
*declarator-id* in `D` is “*derived-declarator-type-list* `noexcept`
|
| 13 |
-
function of
|
| 14 |
-
*ref-qualifier*ₒₚₜ returning `T`”, where
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 18 |
|
| 19 |
In a declaration `T` `D` where `D` has the form
|
| 20 |
|
| 21 |
``` bnf
|
| 22 |
-
'D1 (' parameter-declaration-clause ')' cv-qualifier-seqₒₚₜ
|
| 23 |
ref-qualifierₒₚₜ noexcept-specifierₒₚₜ attribute-specifier-seqₒₚₜ trailing-return-type
|
| 24 |
```
|
| 25 |
|
| 26 |
and the type of the contained *declarator-id* in the declaration `T`
|
| 27 |
`D1` is “*derived-declarator-type-list* `T`”, `T` shall be the single
|
| 28 |
*type-specifier* `auto`. The type of the *declarator-id* in `D` is
|
| 29 |
-
“*derived-declarator-type-list* `noexcept`
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
*trailing-return-type*, and where the optional `noexcept` is present if
|
| 33 |
-
and only if the exception specification is non-throwing. The optional
|
| 34 |
-
*attribute-specifier-seq* appertains to the function type.
|
| 35 |
|
| 36 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 37 |
|
| 38 |
``` bnf
|
| 39 |
parameter-declaration-clause:
|
| 40 |
parameter-declaration-listₒₚₜ '...'ₒₚₜ
|
| 41 |
-
parameter-declaration-list ', ...'
|
| 42 |
```
|
| 43 |
|
| 44 |
``` bnf
|
| 45 |
parameter-declaration-list:
|
| 46 |
parameter-declaration
|
|
@@ -66,17 +75,18 @@ arguments specified on the function call; see
|
|
| 66 |
[[expr.call]]. — *end note*]
|
| 67 |
|
| 68 |
If the *parameter-declaration-clause* is empty, the function takes no
|
| 69 |
arguments. A parameter list consisting of a single unnamed parameter of
|
| 70 |
non-dependent type `void` is equivalent to an empty parameter list.
|
| 71 |
-
Except for this special case, a parameter shall not have type
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
|
|
|
| 78 |
|
| 79 |
[*Example 1*:
|
| 80 |
|
| 81 |
The declaration
|
| 82 |
|
|
@@ -91,31 +101,28 @@ arguments.
|
|
| 91 |
printf("hello world");
|
| 92 |
printf("a=%d b=%d", a, b);
|
| 93 |
```
|
| 94 |
|
| 95 |
However, the first argument must be of a type that can be converted to a
|
| 96 |
-
`const` `char*`
|
| 97 |
|
| 98 |
— *end example*]
|
| 99 |
|
| 100 |
[*Note 2*: The standard header `<cstdarg>` contains a mechanism for
|
| 101 |
accessing arguments passed using the ellipsis (see [[expr.call]] and
|
| 102 |
[[support.runtime]]). — *end note*]
|
| 103 |
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
|
| 114 |
-
forming the function type. The resulting list of transformed parameter
|
| 115 |
-
types and the presence or absence of the ellipsis or a function
|
| 116 |
-
parameter pack is the function’s *parameter-type-list*.
|
| 117 |
|
| 118 |
[*Note 3*: This transformation does not affect the types of the
|
| 119 |
parameters. For example, `int(*)(const int p, decltype(p)*)` and
|
| 120 |
`int(*)(int, const int*)` are identical types. — *end note*]
|
| 121 |
|
|
@@ -125,20 +132,20 @@ A function type with a *cv-qualifier-seq* or a *ref-qualifier*
|
|
| 125 |
|
| 126 |
- the function type for a non-static member function,
|
| 127 |
- the function type to which a pointer to member refers,
|
| 128 |
- the top-level function type of a function typedef declaration or
|
| 129 |
*alias-declaration*,
|
| 130 |
-
- the *type-id* in the default argument of a *type-parameter*
|
| 131 |
-
[[temp.param]]
|
| 132 |
-
- the *type-id* of a *template-argument* for a *type-parameter*
|
| 133 |
-
[[temp.arg.type]]
|
| 134 |
|
| 135 |
[*Example 2*:
|
| 136 |
|
| 137 |
``` cpp
|
| 138 |
typedef int FIC(int) const;
|
| 139 |
-
FIC f; //
|
| 140 |
struct S {
|
| 141 |
FIC f; // OK
|
| 142 |
};
|
| 143 |
FIC S::*pm = &S::f; // OK
|
| 144 |
```
|
|
@@ -164,11 +171,12 @@ struct S {
|
|
| 164 |
|
| 165 |
— *end example*]
|
| 166 |
|
| 167 |
The return type, the parameter-type-list, the *ref-qualifier*, the
|
| 168 |
*cv-qualifier-seq*, and the exception specification, but not the default
|
| 169 |
-
arguments
|
|
|
|
| 170 |
|
| 171 |
[*Note 5*: Function types are checked during the assignments and
|
| 172 |
initializations of pointers to functions, references to functions, and
|
| 173 |
pointers to member functions. — *end note*]
|
| 174 |
|
|
@@ -179,48 +187,52 @@ The declaration
|
|
| 179 |
``` cpp
|
| 180 |
int fseek(FILE*, long, int);
|
| 181 |
```
|
| 182 |
|
| 183 |
declares a function taking three arguments of the specified types, and
|
| 184 |
-
returning `int`
|
| 185 |
|
| 186 |
— *end example*]
|
| 187 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 188 |
Functions shall not have a return type of type array or function,
|
| 189 |
although they may have a return type of type pointer or reference to
|
| 190 |
such things. There shall be no arrays of functions, although there can
|
| 191 |
be arrays of pointers to functions.
|
| 192 |
|
| 193 |
-
|
| 194 |
-
|
| 195 |
-
|
| 196 |
-
|
| 197 |
-
[[dcl.fct.def.delete]]).
|
| 198 |
|
| 199 |
A typedef of function type may be used to declare a function but shall
|
| 200 |
-
not be used to define a function
|
| 201 |
|
| 202 |
[*Example 5*:
|
| 203 |
|
| 204 |
``` cpp
|
| 205 |
typedef void F();
|
| 206 |
F fv; // OK: equivalent to void fv();
|
| 207 |
-
F fv { } //
|
| 208 |
void fv() { } // OK: definition of fv
|
| 209 |
```
|
| 210 |
|
| 211 |
— *end example*]
|
| 212 |
|
| 213 |
An identifier can optionally be provided as a parameter name; if present
|
| 214 |
-
in a function definition
|
| 215 |
|
| 216 |
[*Note 6*: In particular, parameter names are also optional in function
|
| 217 |
definitions and names used for a parameter in different declarations and
|
| 218 |
the definition of a function need not be the same. If a parameter name
|
| 219 |
is present in a function declaration that is not a definition, it cannot
|
| 220 |
be used outside of its function declarator because that is the extent of
|
| 221 |
-
its potential scope
|
| 222 |
|
| 223 |
[*Example 6*:
|
| 224 |
|
| 225 |
The declaration
|
| 226 |
|
|
@@ -285,24 +297,101 @@ template <class T, class U> decltype((*(T*)0) + (*(U*)0)) add(T t, U u);
|
|
| 285 |
A *non-template function* is a function that is not a function template
|
| 286 |
specialization.
|
| 287 |
|
| 288 |
[*Note 8*: A function template is not a function. — *end note*]
|
| 289 |
|
| 290 |
-
|
| 291 |
-
|
| 292 |
-
|
| 293 |
-
|
| 294 |
-
|
| 295 |
-
|
| 296 |
-
|
| 297 |
-
*
|
| 298 |
-
|
| 299 |
-
|
| 300 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 301 |
|
| 302 |
[*Example 7*:
|
| 303 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 304 |
``` cpp
|
| 305 |
template<typename... T> void f(T (* ...t)(int, int));
|
| 306 |
|
| 307 |
int add(int, int);
|
| 308 |
float subtract(int, int);
|
|
@@ -317,7 +406,7 @@ void g() {
|
|
| 317 |
There is a syntactic ambiguity when an ellipsis occurs at the end of a
|
| 318 |
*parameter-declaration-clause* without a preceding comma. In this case,
|
| 319 |
the ellipsis is parsed as part of the *abstract-declarator* if the type
|
| 320 |
of the parameter either names a template parameter pack that has not
|
| 321 |
been expanded or contains `auto`; otherwise, it is parsed as part of the
|
| 322 |
-
*parameter-declaration-clause*.[^
|
| 323 |
|
|
|
|
| 1 |
+
#### Functions <a id="dcl.fct">[[dcl.fct]]</a>
|
| 2 |
|
| 3 |
In a declaration `T` `D` where `D` has the form
|
| 4 |
|
| 5 |
``` bnf
|
| 6 |
+
'D1' '(' parameter-declaration-clause ')' cv-qualifier-seqₒₚₜ
|
| 7 |
ref-qualifierₒₚₜ noexcept-specifierₒₚₜ attribute-specifier-seqₒₚₜ
|
| 8 |
```
|
| 9 |
|
| 10 |
and the type of the contained *declarator-id* in the declaration `T`
|
| 11 |
`D1` is “*derived-declarator-type-list* `T`”, the type of the
|
| 12 |
+
*declarator-id* in `D` is “*derived-declarator-type-list* `noexcept`ₒₚₜ
|
| 13 |
+
function of parameter-type-list *cv-qualifier-seq*ₒₚₜ
|
| 14 |
+
*ref-qualifier*ₒₚₜ returning `T`”, where
|
| 15 |
+
|
| 16 |
+
- the parameter-type-list is derived from the
|
| 17 |
+
*parameter-declaration-clause* as described below and
|
| 18 |
+
- the optional `noexcept` is present if and only if the exception
|
| 19 |
+
specification [[except.spec]] is non-throwing.
|
| 20 |
+
|
| 21 |
+
The optional *attribute-specifier-seq* appertains to the function type.
|
| 22 |
|
| 23 |
In a declaration `T` `D` where `D` has the form
|
| 24 |
|
| 25 |
``` bnf
|
| 26 |
+
'D1' '(' parameter-declaration-clause ')' cv-qualifier-seqₒₚₜ
|
| 27 |
ref-qualifierₒₚₜ noexcept-specifierₒₚₜ attribute-specifier-seqₒₚₜ trailing-return-type
|
| 28 |
```
|
| 29 |
|
| 30 |
and the type of the contained *declarator-id* in the declaration `T`
|
| 31 |
`D1` is “*derived-declarator-type-list* `T`”, `T` shall be the single
|
| 32 |
*type-specifier* `auto`. The type of the *declarator-id* in `D` is
|
| 33 |
+
“*derived-declarator-type-list* `noexcept`ₒₚₜ function of
|
| 34 |
+
parameter-type-list *cv-qualifier-seq*ₒₚₜ *ref-qualifier*ₒₚₜ returning
|
| 35 |
+
`U`”, where
|
|
|
|
|
|
|
|
|
|
| 36 |
|
| 37 |
+
- the parameter-type-list is derived from the
|
| 38 |
+
*parameter-declaration-clause* as described below,
|
| 39 |
+
- `U` is the type specified by the *trailing-return-type*, and
|
| 40 |
+
- the optional `noexcept` is present if and only if the exception
|
| 41 |
+
specification is non-throwing.
|
| 42 |
+
|
| 43 |
+
The optional *attribute-specifier-seq* appertains to the function type.
|
| 44 |
+
|
| 45 |
+
A type of either form is a *function type*.[^2]
|
| 46 |
|
| 47 |
``` bnf
|
| 48 |
parameter-declaration-clause:
|
| 49 |
parameter-declaration-listₒₚₜ '...'ₒₚₜ
|
| 50 |
+
parameter-declaration-list ',' '...'
|
| 51 |
```
|
| 52 |
|
| 53 |
``` bnf
|
| 54 |
parameter-declaration-list:
|
| 55 |
parameter-declaration
|
|
|
|
| 75 |
[[expr.call]]. — *end note*]
|
| 76 |
|
| 77 |
If the *parameter-declaration-clause* is empty, the function takes no
|
| 78 |
arguments. A parameter list consisting of a single unnamed parameter of
|
| 79 |
non-dependent type `void` is equivalent to an empty parameter list.
|
| 80 |
+
Except for this special case, a parameter shall not have type cv `void`.
|
| 81 |
+
A parameter with volatile-qualified type is deprecated; see
|
| 82 |
+
[[depr.volatile.type]]. If the *parameter-declaration-clause* terminates
|
| 83 |
+
with an ellipsis or a function parameter pack [[temp.variadic]], the
|
| 84 |
+
number of arguments shall be equal to or greater than the number of
|
| 85 |
+
parameters that do not have a default argument and are not function
|
| 86 |
+
parameter packs. Where syntactically correct and where “`...`” is not
|
| 87 |
+
part of an *abstract-declarator*, “`, ...`” is synonymous with “`...`”.
|
| 88 |
|
| 89 |
[*Example 1*:
|
| 90 |
|
| 91 |
The declaration
|
| 92 |
|
|
|
|
| 101 |
printf("hello world");
|
| 102 |
printf("a=%d b=%d", a, b);
|
| 103 |
```
|
| 104 |
|
| 105 |
However, the first argument must be of a type that can be converted to a
|
| 106 |
+
`const` `char*`.
|
| 107 |
|
| 108 |
— *end example*]
|
| 109 |
|
| 110 |
[*Note 2*: The standard header `<cstdarg>` contains a mechanism for
|
| 111 |
accessing arguments passed using the ellipsis (see [[expr.call]] and
|
| 112 |
[[support.runtime]]). — *end note*]
|
| 113 |
|
| 114 |
+
The type of a function is determined using the following rules. The type
|
| 115 |
+
of each parameter (including function parameter packs) is determined
|
| 116 |
+
from its own *decl-specifier-seq* and *declarator*. After determining
|
| 117 |
+
the type of each parameter, any parameter of type “array of `T`” or of
|
| 118 |
+
function type `T` is adjusted to be “pointer to `T`”. After producing
|
| 119 |
+
the list of parameter types, any top-level *cv-qualifier*s modifying a
|
| 120 |
+
parameter type are deleted when forming the function type. The resulting
|
| 121 |
+
list of transformed parameter types and the presence or absence of the
|
| 122 |
+
ellipsis or a function parameter pack is the function’s
|
| 123 |
+
*parameter-type-list*.
|
|
|
|
|
|
|
|
|
|
| 124 |
|
| 125 |
[*Note 3*: This transformation does not affect the types of the
|
| 126 |
parameters. For example, `int(*)(const int p, decltype(p)*)` and
|
| 127 |
`int(*)(int, const int*)` are identical types. — *end note*]
|
| 128 |
|
|
|
|
| 132 |
|
| 133 |
- the function type for a non-static member function,
|
| 134 |
- the function type to which a pointer to member refers,
|
| 135 |
- the top-level function type of a function typedef declaration or
|
| 136 |
*alias-declaration*,
|
| 137 |
+
- the *type-id* in the default argument of a *type-parameter*
|
| 138 |
+
[[temp.param]], or
|
| 139 |
+
- the *type-id* of a *template-argument* for a *type-parameter*
|
| 140 |
+
[[temp.arg.type]].
|
| 141 |
|
| 142 |
[*Example 2*:
|
| 143 |
|
| 144 |
``` cpp
|
| 145 |
typedef int FIC(int) const;
|
| 146 |
+
FIC f; // error: does not declare a member function
|
| 147 |
struct S {
|
| 148 |
FIC f; // OK
|
| 149 |
};
|
| 150 |
FIC S::*pm = &S::f; // OK
|
| 151 |
```
|
|
|
|
| 171 |
|
| 172 |
— *end example*]
|
| 173 |
|
| 174 |
The return type, the parameter-type-list, the *ref-qualifier*, the
|
| 175 |
*cv-qualifier-seq*, and the exception specification, but not the default
|
| 176 |
+
arguments [[dcl.fct.default]] or the trailing *requires-clause*
|
| 177 |
+
[[dcl.decl]], are part of the function type.
|
| 178 |
|
| 179 |
[*Note 5*: Function types are checked during the assignments and
|
| 180 |
initializations of pointers to functions, references to functions, and
|
| 181 |
pointers to member functions. — *end note*]
|
| 182 |
|
|
|
|
| 187 |
``` cpp
|
| 188 |
int fseek(FILE*, long, int);
|
| 189 |
```
|
| 190 |
|
| 191 |
declares a function taking three arguments of the specified types, and
|
| 192 |
+
returning `int` [[dcl.type]].
|
| 193 |
|
| 194 |
— *end example*]
|
| 195 |
|
| 196 |
+
A single name can be used for several different functions in a single
|
| 197 |
+
scope; this is function overloading [[over]]. All declarations for a
|
| 198 |
+
function shall have equivalent return types, parameter-type-lists, and
|
| 199 |
+
*requires-clause*s [[temp.over.link]].
|
| 200 |
+
|
| 201 |
Functions shall not have a return type of type array or function,
|
| 202 |
although they may have a return type of type pointer or reference to
|
| 203 |
such things. There shall be no arrays of functions, although there can
|
| 204 |
be arrays of pointers to functions.
|
| 205 |
|
| 206 |
+
A volatile-qualified return type is deprecated; see
|
| 207 |
+
[[depr.volatile.type]].
|
| 208 |
+
|
| 209 |
+
Types shall not be defined in return or parameter types.
|
|
|
|
| 210 |
|
| 211 |
A typedef of function type may be used to declare a function but shall
|
| 212 |
+
not be used to define a function [[dcl.fct.def]].
|
| 213 |
|
| 214 |
[*Example 5*:
|
| 215 |
|
| 216 |
``` cpp
|
| 217 |
typedef void F();
|
| 218 |
F fv; // OK: equivalent to void fv();
|
| 219 |
+
F fv { } // error
|
| 220 |
void fv() { } // OK: definition of fv
|
| 221 |
```
|
| 222 |
|
| 223 |
— *end example*]
|
| 224 |
|
| 225 |
An identifier can optionally be provided as a parameter name; if present
|
| 226 |
+
in a function definition [[dcl.fct.def]], it names a parameter.
|
| 227 |
|
| 228 |
[*Note 6*: In particular, parameter names are also optional in function
|
| 229 |
definitions and names used for a parameter in different declarations and
|
| 230 |
the definition of a function need not be the same. If a parameter name
|
| 231 |
is present in a function declaration that is not a definition, it cannot
|
| 232 |
be used outside of its function declarator because that is the extent of
|
| 233 |
+
its potential scope [[basic.scope.param]]. — *end note*]
|
| 234 |
|
| 235 |
[*Example 6*:
|
| 236 |
|
| 237 |
The declaration
|
| 238 |
|
|
|
|
| 297 |
A *non-template function* is a function that is not a function template
|
| 298 |
specialization.
|
| 299 |
|
| 300 |
[*Note 8*: A function template is not a function. — *end note*]
|
| 301 |
|
| 302 |
+
An *abbreviated function template* is a function declaration that has
|
| 303 |
+
one or more generic parameter type placeholders [[dcl.spec.auto]]. An
|
| 304 |
+
abbreviated function template is equivalent to a function template
|
| 305 |
+
[[temp.fct]] whose *template-parameter-list* includes one invented type
|
| 306 |
+
*template-parameter* for each generic parameter type placeholder of the
|
| 307 |
+
function declaration, in order of appearance. For a
|
| 308 |
+
*placeholder-type-specifier* of the form `auto`, the invented parameter
|
| 309 |
+
is an unconstrained *type-parameter*. For a *placeholder-type-specifier*
|
| 310 |
+
of the form *type-constraint* `auto`, the invented parameter is a
|
| 311 |
+
*type-parameter* with that *type-constraint*. The invented type
|
| 312 |
+
*template-parameter* is a template parameter pack if the corresponding
|
| 313 |
+
*parameter-declaration* declares a function parameter pack [[dcl.fct]].
|
| 314 |
+
If the placeholder contains `decltype(auto)`, the program is ill-formed.
|
| 315 |
+
The adjusted function parameters of an abbreviated function template are
|
| 316 |
+
derived from the *parameter-declaration-clause* by replacing each
|
| 317 |
+
occurrence of a placeholder with the name of the corresponding invented
|
| 318 |
+
*template-parameter*.
|
| 319 |
|
| 320 |
[*Example 7*:
|
| 321 |
|
| 322 |
+
``` cpp
|
| 323 |
+
template<typename T> concept C1 = /* ... */;
|
| 324 |
+
template<typename T> concept C2 = /* ... */;
|
| 325 |
+
template<typename... Ts> concept C3 = /* ... */;
|
| 326 |
+
|
| 327 |
+
void g1(const C1 auto*, C2 auto&);
|
| 328 |
+
void g2(C1 auto&...);
|
| 329 |
+
void g3(C3 auto...);
|
| 330 |
+
void g4(C3 auto);
|
| 331 |
+
```
|
| 332 |
+
|
| 333 |
+
These declarations are functionally equivalent (but not equivalent) to
|
| 334 |
+
the following declarations.
|
| 335 |
+
|
| 336 |
+
``` cpp
|
| 337 |
+
template<C1 T, C2 U> void g1(const T*, U&);
|
| 338 |
+
template<C1... Ts> void g2(Ts&...);
|
| 339 |
+
template<C3... Ts> void g3(Ts...);
|
| 340 |
+
template<C3 T> void g4(T);
|
| 341 |
+
```
|
| 342 |
+
|
| 343 |
+
Abbreviated function templates can be specialized like all function
|
| 344 |
+
templates.
|
| 345 |
+
|
| 346 |
+
``` cpp
|
| 347 |
+
template<> void g1<int>(const int*, const double&); // OK, specialization of g1<int, const double>
|
| 348 |
+
```
|
| 349 |
+
|
| 350 |
+
— *end example*]
|
| 351 |
+
|
| 352 |
+
An abbreviated function template can have a *template-head*. The
|
| 353 |
+
invented *template-parameters* are appended to the
|
| 354 |
+
*template-parameter-list* after the explicitly declared
|
| 355 |
+
*template-parameters*.
|
| 356 |
+
|
| 357 |
+
[*Example 8*:
|
| 358 |
+
|
| 359 |
+
``` cpp
|
| 360 |
+
template<typename> concept C = /* ... */;
|
| 361 |
+
|
| 362 |
+
template <typename T, C U>
|
| 363 |
+
void g(T x, U y, C auto z);
|
| 364 |
+
```
|
| 365 |
+
|
| 366 |
+
This is functionally equivalent to each of the following two
|
| 367 |
+
declarations.
|
| 368 |
+
|
| 369 |
+
``` cpp
|
| 370 |
+
template<typename T, C U, C W>
|
| 371 |
+
void g(T x, U y, W z);
|
| 372 |
+
|
| 373 |
+
template<typename T, typename U, typename W>
|
| 374 |
+
requires C<U> && C<W>
|
| 375 |
+
void g(T x, U y, W z);
|
| 376 |
+
```
|
| 377 |
+
|
| 378 |
+
— *end example*]
|
| 379 |
+
|
| 380 |
+
A function declaration at block scope shall not declare an abbreviated
|
| 381 |
+
function template.
|
| 382 |
+
|
| 383 |
+
A *declarator-id* or *abstract-declarator* containing an ellipsis shall
|
| 384 |
+
only be used in a *parameter-declaration*. When it is part of a
|
| 385 |
+
*parameter-declaration-clause*, the *parameter-declaration* declares a
|
| 386 |
+
function parameter pack [[temp.variadic]]. Otherwise, the
|
| 387 |
+
*parameter-declaration* is part of a *template-parameter-list* and
|
| 388 |
+
declares a template parameter pack; see [[temp.param]]. A function
|
| 389 |
+
parameter pack is a pack expansion [[temp.variadic]].
|
| 390 |
+
|
| 391 |
+
[*Example 9*:
|
| 392 |
+
|
| 393 |
``` cpp
|
| 394 |
template<typename... T> void f(T (* ...t)(int, int));
|
| 395 |
|
| 396 |
int add(int, int);
|
| 397 |
float subtract(int, int);
|
|
|
|
| 406 |
There is a syntactic ambiguity when an ellipsis occurs at the end of a
|
| 407 |
*parameter-declaration-clause* without a preceding comma. In this case,
|
| 408 |
the ellipsis is parsed as part of the *abstract-declarator* if the type
|
| 409 |
of the parameter either names a template parameter pack that has not
|
| 410 |
been expanded or contains `auto`; otherwise, it is parsed as part of the
|
| 411 |
+
*parameter-declaration-clause*.[^3]
|
| 412 |
|