P0780 ("Allow pack expansion in lambda init-capture"), approved for C++20, allows to generate a pack of closure data members by placing an ellipsis (...
) before a pack expansion as part of a lambda capture.
This is useful - for example - when capturing a pack by move:
template <typename... Ts>
void foo(Ts... xs)
{
bar([...xs = std::move(xs)]{ /* ... */ });
}
While playing around with this feature, I came up with this cryptic construction:
template <typename... Ts>
void foo(Ts... xs)
{
[...xs...]{}();
}
int main()
{
foo(0, 1, 2);
}
live example on godbolt.org
g++ (trunk) compiles it, but I am honestly struggling to understand its meaning. What is this supposed to mean? What will the generate closure have as data members?
The lambda is capturing an outside variable. A lambda is a syntax for creating a class. Capturing a variable means that variable is passed to the constructor for that class. A lambda can specify whether it's passed by reference or by value.
When a lambda object outlives one of its reference-captured objects, execution of the lambda object's function call operator results in undefined behavior once that reference-captured object is accessed. Therefore, a lambda object must not outlive any of its reference-captured objects.
In C++11 and later, a lambda expression—often called a lambda—is a convenient way of defining an anonymous function object (a closure) right at the location where it's invoked or passed as an argument to a function.
What is the correct statement about lambda expression? Explanation: Return type in lambda expression can be ignored in some cases as the compiler will itself figure that out but not in all cases. Lambda expression is used to define small functions, not large functions.
It should be ill-formed. Filed 89686 (... and already fixed!) The grammar in [expr.prim.lambda.capture] is:
capture:
simple-capture...
opt
...
optinit-capture
You can either have a simple-capture (which would be xs...
) or you can have an init-capture (which would be ...xs=xs
, an init-capture needs to have an initializer). You cannot have both in one go.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With