c++templateslambdalanguage-lawyerc++20

Are captureless lambdas structural types?


P1907R1, accepted for C++20, introduced structural types, which are a valid types for non-type template parameter.

GCC and Clang both accepts the following snippet for C++2a:

template<auto v>
constexpr auto identity_v = v;

constexpr auto l1 = [](){};
constexpr auto l2 = identity_v<l1>; 

implying that the type of a captureless lambda is a structural type.

Question

  • Does a captureless lambda indeed fulfill the requirements for its type to to be a structural type?

Solution

  • With the resolution of defect report CWG2542, lambdas—regardless of being captureless—are now explicitly defined not to be of structural type and can therefore not be used as NTTPs. This means that compilers could implement CWG2542 at any point and reject C++20 (or newer) code that tries to use any type of lambda as an NTTP.

    The relevant passage of 7.5.5.2 ([expr.prim.lambda.closure]) paragraph 3 will now read as:

    The closure type is not an aggregate type ([dcl.init.aggr]) and not a structural type ([temp.param]).