This paper contains formal wording for the two extensions proposed in P0766r1: Fixing small-ish functionality gaps in constraints that concern requires-clauses.
Modify the grammar in [expr.prim.lambda, 8.1.5] as follows.
<
template-parameter-list
>
requires-clauseopt compound-statement<
template-parameter-list
>
requires-clauseopt lambda-declaratorModify [expr.prim.lambda, 8.1.5] paragraph 3 as follows.
mutable
or constexpr
.
[Note: The trailing requires-clause is described in Clause [dcl.decl, 11]. – end note]Modify [expr.prim.lambda, 8.1.5.1] paragraph 3 as follows.
auto
in the lambda’s parameter-declaration-clause, in order of appearance.
The invented type template-parameter is a parameter pack if the corresponding parameter-declaration declares a function parameter
pack (11.3.5).
The return type and function parameters of the function call operator template are derived from
the lambda-expression’s trailing-return-type and parameter-declaration-clause
by replacing each occurrence of auto in the decl-specifiers of the parameter-declaration-clause with the name of the corresponding invented
template-parameter.
The requires-clause of the function call operator template is the requires-clause
immediately following <
template-parameter-list >
, if any. The trailing requires-clause of the
function call operator or operator template is the requires-clause following the lambda-declarator, if any.
[Example: […]
Modify [expr.prim.lambda, 8.1.5.1] paragraph 6 as follows.
noexcept
function” if the function
call operator has a non-throwing exception specification.
The value returned by this conversion function is the address of a function F
that,
when invoked, has the same effect as […]
Insert a new paragraph between paragraphs 5 and 6 of [expr.prim.lambda.closure, 8.1.5.1].
[…] – end example]
The function call operator or operator template may be constrained ([temp.constr.decl, 17.4.2]) by a constrained-parameter ([temp.param, 17.1]), a requires-clause (Clause [temp, 17]), or a trailing requires-clause (Clause [dcl.decl, 11]). [Example:
– end example]
The closure type for a non-generic lambda-expression […]
Modify the grammar in [temp.param, 17.1] as follows.
...
opt identifieropt=
type-idtemplate <
template-parameter-list >
...
opt identifieropttemplate <
template-parameter-list >
Modify [temp.arg.template, 17.3.3], paragraph 3 as follows.
P
when P
is at least as specialized as the template-argument A
. If P
contains a parameter
pack, then A
also matches P
if each of A
’s template parameters
matches the corresponding template parameter in the P
. Two template parameters
match if they are of the same kind (type, non-type, template), for non-type template-parameters, their types are
equivalent (17.6.6.1), and for template template-parameters, each of their corresponding template-parameters
matches, recursively. When P
’s A
with the same type and form as the template parameter pack in P
(ignoring
whether those template parameters are template parameter packs).
[Example: […]Modify [temp.arg.template, 17.3.3], paragraph 4 as follows.
A template template-parameter P
is at least as specialized as a template template-argument A
if, given
the following rewrite to two function templates, the function template corresponding to P
is at least as
specialized as the function template corresponding to A
according to the partial ordering rules for function
templates (17.6.6.2). Given an invented class template X
with the template parameter listtemplate-head of A
(including
default arguments and requires-clause, if any):
P
or A
.
X
with template
arguments corresponding to the template parameters from the respective function template where, for
each template parameter PP
in the AA
is formed. If PP
declares a parameter pack, then AA
is the pack expansion
PP...
(17.6.3); otherwise, AA
is the id-expression PP
.
If the rewrite produces an invalid type, then P
is not at least as specialized as A
.