Vittorio Romeo
Vittorio Romeo

Reputation: 93364

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?

Upvotes: 18

Views: 777

Answers (1)

Barry
Barry

Reputation: 303537

It should be ill-formed. Filed 89686 (... and already fixed!) The grammar in [expr.prim.lambda.capture] is:

capture:
    simple-capture ...opt
    ...opt init-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.

Upvotes: 18

Related Questions