10 KiB
[expr.prim.lambda.general]
7 Expressions [expr]
7.5 Primary expressions [expr.prim]
7.5.6 Lambda expressions [expr.prim.lambda]
7.5.6.1 General [expr.prim.lambda.general]
lambda-expression:
lambda-introducer attribute-specifier-seqopt lambda-declarator compound-statement
lambda-introducer < template-parameter-list > requires-clauseopt attribute-specifier-seqopt
lambda-declarator compound-statement
lambda-introducer:
[ lambda-captureopt ]
lambda-declarator:
lambda-specifier-seq noexcept-specifieropt attribute-specifier-seqopt trailing-return-typeopt
function-contract-specifier-seqopt
noexcept-specifier attribute-specifier-seqopt trailing-return-typeopt function-contract-specifier-seqopt
trailing-return-typeopt function-contract-specifier-seqopt
( parameter-declaration-clause ) lambda-specifier-seqopt noexcept-specifieropt attribute-specifier-seqopt
trailing-return-typeopt requires-clauseopt function-contract-specifier-seqopt
lambda-specifier:
consteval
constexpr
mutable
static
lambda-specifier-seq:
lambda-specifier lambda-specifier-seqopt
A lambda-expression provides a concise way to create a simple function object.
[Example 1: #include #include void abssort(float* x, unsigned N) { std::sort(x, x + N, [](float a, float b) { return std::abs(a) < std::abs(b); });} â end example]
A lambda-expression is a prvalue whose result object is called the closure object.
[Note 1:
A closure object behaves like a function object.
â end note]
An ambiguity can arise because a requires-clause can end in an attribute-specifier-seq, which collides with the attribute-specifier-seq in lambda-expression.
In such cases, any attributes are treated asattribute-specifier-seq in lambda-expression.
[Note 2:
Such ambiguous cases cannot have valid semantics because the constraint expression would not have type bool.
[Example 2: auto x = [] requires T::operator int some_attribute (int) { } â end example]
â end note]
A lambda-specifier-seq shall contain at most one of each lambda-specifier and shall not contain both constexpr and consteval.
If the lambda-declarator contains an explicit object parameter ([dcl.fct]), then no lambda-specifier in the lambda-specifier-seq shall be mutable or static.
The lambda-specifier-seq shall not contain both mutable and static.
If the lambda-specifier-seq contains static, there shall be no lambda-capture.
[Note 3:
The trailing requires-clause is described in [dcl.decl].
â end note]
A lambda-expression's parameter-declaration-clause is the parameter-declaration-clause of the lambda-expression's lambda-declarator, if any, or empty otherwise.
If the lambda-declarator does not include a trailing-return-type, it is considered to be -> auto.
[Note 4:
In that case, the return type is deduced from return statements as described in [dcl.spec.auto].
â end note]
[Example 3: auto x1 = [](int i) { return i; }; // OK, return type is intauto x2 = []{ return { 1, 2 }; }; // error: deducing return type from braced-init-listint j;auto x3 = &->auto&& { return j; }; // OK, return type is int& â end example]
A lambda is a generic lambda if the lambda-expression has any generic parameter type placeholders ([dcl.spec.auto]), or if the lambda has a template-parameter-list.
[Example 4: auto x = [](int i, auto a) { return i; }; // OK, a generic lambdaauto y = [](this auto self, int i) { return i; }; // OK, a generic lambdaauto z = [](int i) { return i; }; // OK, a generic lambda â end example]