18

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?

Vittorio Romeo
  • 90,666
  • 33
  • 258
  • 416

1 Answers1

18

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.

Sasha
  • 102
  • 8
Barry
  • 286,269
  • 29
  • 621
  • 977