There once was a long disscusion going on whether closure types should be considered as structural types or not (essentially determining whether they would be eligible as NTTPs). An elaborated post about this, made by user dfrib, can be found here.
The initial concern about this seemed to be raised by Zhihao Yuan, back in March 2022. This ended up becoming defect report CWG 2542, which was accepted by a working group meeting in June 2023. The proposed resolution of that defect report was approved and it very clearly stated that closure types are not structural types.
This change was reflected in many versions of the C++ Working Draft, at least all the way up to N4971. The passage of interest being listed under [expr.prim.lambda.closure]/3
. This is also what people will find when looking up the cppreference entry about lambdas, which references defect report CWG 2542 at the bottom of the page.
However, in the more recent C++ Working Draft version N4981, passage [expr.prim.lambda.closure]/3 now reads:
The closure type is not an aggregate type (9.4.2); it is a structural type (13.2) if and only if the lambda has no lambda-capture.
Which seems to revert the approved resolution of defect report CWG 2542. Should this defect report now be considered obsolete? And, by which meeting/decision/paper did closure types now become structural types?
And, by which meeting/decision/paper did closure types now become structural types?
This was CWG2845 whose proposed and accepted resolution was to make a captureless lambda a structural type.
This can be seen from CWG2845:
Make the closure type of a captureless lambda a structural type
Issue 2542 (approved in June, 2023) made all closure types not be structural types, i.e. unsuitable for use as non-type template parameters. This causes an inconsistency with the treatment of the pointer-to-function conversion for closure types with no captures:
Proposed resolution (approved by CWG 2024-02-02):
Change in 7.5.5.2 [expr.prim.lambda.closure] paragraph 3 as follows:
- The closure type is not an aggregate type (9.4.2 [dcl.init.aggr]) and not ; it is a structural type (13.2 [temp.param]) if and only if the lambda has no lambda-capture. An implementation may define the closure type differently from ...