This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCH to overhaul lambdas in templates


Our old model for handling lambdas in templates was to handle them
like any other template class, and instantiate them by normal
substitution.  This was insufficient for lambdas for two reasons: for
one, it made it impossible to get implicit captures quite right in
templates.

Also, if a lambda appears in a pack expansion, e.g.

template <class... T>
auto f() {
  int i = 42;
  return ([i]{ return T(i); }() + ...);
}

There needs to be one lambda for each element of T, not just one for
each instantiation of f.  So instantiating a LAMBDA_EXPR needs to
build up a new LAMBDA_EXPR each time.  This patch implements that,
primarily in the new tsubst_lambda_expr function.

Generating the op() decl for the new lambda is a lot like a normal
instantiation, but not quite.  I decided to do this by factoring out
tsubst_function_decl and tsubst_template_decl, and having them handle
the lambda special case appropriately: when we're dealing with the
lambda function, it isn't actually a specialization of the lambda in
the template, and it isn't a member of a specialization of the closure
in the template.

The code in process_outer_var_ref for handling generic lambdas
specifically can now go away; we now defer implicit capture until the
enclosing context is instantiated for generic and non-generic lambdas.

Tested x86_64-pc-linux-gnu, applying to trunk.

Attachment: lambda-rewrite.diff
Description: Text document


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]