cplusplus / CWG

Core Working Group
23 stars 7 forks source link

[expr.prim.lambda.capture] Insufficient requirements for additional non-static data members for by-reference captures #491

Closed frederick-vs-ja closed 5 months ago

frederick-vs-ja commented 5 months ago

Full name of submitter (unless configured in github; will be published with the issue): Jiang An

Reference (section label): [expr.prim.lambda.capture]

Link to reflector thread (if any): https://lists.isocpp.org/std-proposals/2024/01/8856.php

Issue description:

[expr.prim.lambda.capture] p12 currently says:

[...] If declared, such non-static data members shall be of literal type.

The sentence was added by P0170R1, which intended to make sure that by-reference captures wouldn't accidently make constant evaluation fail.

However, it seems too loose to just specify the types to be literal type. E.g. in the following example

static_assert([]
{
  int x{};
  auto a = [&x]{ return true; };
  auto b = a; // Must the copy construction be a constant subexpression?
  return b();
}());

the copy construction is not yet guaranteed be a constant subexpression and thus the static_assert is not yet guaranteed to pass, because the definition of literal type ([basic.types.general] p10) doesn't concern copy/move construction.

Perhaps we should specify that the initialization from the corresponding capture(s) and the copy/move construction of such a non-static data member shall not additionally cause constant evaluation failure.

Suggested resolution:

jensmaurer commented 5 months ago

Copying of closure types is a fairly rare operation. Is there any example in the standard that demonstrates that copying closure types was intended to be constexpr? I'm not finding such an example in P0170R1, either.

As such, this seems a desire for an additional feature, not a wording bug fix. Please write a (possibly short) paper for consideration by EWG.