[cfe-dev] C++2a default-constructible and assignable lambdas

Logan Smith via cfe-dev cfe-dev at lists.llvm.org
Mon Jul 1 10:10:21 PDT 2019


Salutations all -- brand-new, aspiring Clang hacker here.

In spelunking through AST/DeclCXX.cpp to familiarize myself with things, I
stumbled upon the implementation
of CXXRecordDecl::lambdaIsDefaultConstructibleAndAssignable(). It -- very
conveniently -- cites the C++2a draft as per new rules involving lambda
default construction and assignment:

  C++2a [expr.prim.lambda.capture]p11:
    The closure type associated with a lambda-expression has no default
    constructor if the lambda-expression has a lambda-capture and a
    defaulted default constructor otherwise. It has a deleted copy
    assignment operator if the lambda-expression has a lambda-capture and
    defaulted copy and move assignment operators otherwise.

By my reading, if a lambda has any captures whatsoever, its default
constructor and copy assignment operators are deleted. However, the
implementation in clang appears to only check for the presence of
`capture-default`s:

  if (getLambdaCaptureDefault() != LCD_None)
    return false;
  return getASTContext().getLangOpts().CPlusPlus2a;

In fact, the commit where this feature was introduced (864949bda1db) very
explicitly only provides for lambdas with `capture-default's. This leads
the following code to be (erroneously, by my reading) accepted by clang
with -std=c++2a:

    void f(int i) {
        auto lam1 = [i] {};
        decltype(lam1) lam2;
    }

while the following is (correctly) rejected:

    void f(int i) {
        auto lam1 = [=] {};
        decltype(lam1) lam2;
    }

My question is: is the current implementation 1) intentional, and 2)
correct?

-- logan
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20190701/3e2c4c69/attachment.html>


More information about the cfe-dev mailing list