Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lambda pack capture with ellipsis on both sides - what is the meaning?

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?

like image 323
Vittorio Romeo Avatar asked Mar 12 '19 17:03

Vittorio Romeo


People also ask

What does it mean to lambda capture this?

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.

What happens when a lambda goes out of scope?

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.

What are lambda expressions in C++?

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?

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.


1 Answers

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.

like image 181
Barry Avatar answered Dec 02 '22 03:12

Barry