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.