I haven't been following GCC, so I need to thank Jason for forwarding this issue to me.

I just read through the messages on the list, and had some more comments:

+    /* relayout again -- to allow for implicit
+     * parameters to have been added to the capture if it was a
+     * 'default capture' -- note that this would not be necessary if
+     * the stack-pointer variant was implemented -- since the layout
+     * would be known.
+     * Relayingout here might have nasty effect if one were to query
+     * sizeof *this from within the body -- would that even be
+     * possible -- *this would refer to the lambda or the enclosing
+     * class instance -- if there was one.???
+     *
+     * NOTE: I think this is a redefinition error; I'm just faking that
+     * it isn't by clearing the size node... need to use stack pointer
+     * method.  But that will likely bring its own issues -- not with
+     * class layout though.
+     */
+    TYPE_SIZE (type) = NULL_TREE;
+    finish_struct_1 (type);

Relaying out the class after the lambda body was parsed is something I had attempted to do, but possibly failed at. It will absolutely need to be done.

The way 'default reference capture' is implemented on the lambda branch seems 
to be kind of reactive.  I would expect
that inheriting the stack somehow (maybe using just a stack pointer) would be 
better but without more investigation I
don't know if that is possible or how one would go about doing it.

This won't be suitable in the general case, because of the copy default capture [=]. Implicit captures will have to be reactive.

/*
 * Rather than looping through the identifiers used in the scope of
 * the lambda and synthesizing individual captures of them, it would
 * be better to ref the stack frame as transparently as possible...
 * e.g. given just three ints i, j and k in scope:
 * Instead of transforming:
 *
 *    [&] { i = 1; j = 2; k = 3; };
 *
 * into
 *
 *    [&i,&j,&k] { i = 1; j = 2; k = 3; };
 *
 * and thus storing three pointers to int, transform it into:
 *
 *    [sp=enclosing-stack-pointer] { var-from-stack(i,sp) = 1;
 *                                   var-from-stack(j,sp) = 2;
 *                                   var-from-stack(k,sp) = 3; };
 *
 * and only store one pointer.

This is preferred for reference default captures, but I was not familiar with stack pointer mechanics in GCC. I just wanted to get something working first that could be improved later.

 * I don't know if its possible but it may be possible to 'append'
 * the lambda's stack to the existing scope rather than creating a
 * new constrained scope -- from a logical point of view.

Again, this is not suitable to the general case because a lambda can outlast its enclosing scope.

My motivation for investigating is that I consider constraining lambdas to be 
monomorphic significantly reduces their
usefulness.   I'm sure there are many good reasons why the committee decided 
that it was the way to go.

I don't think it handicaps lambdas as much as some may believe, but still wanted polymorphic lambdas as well. There were just too many issues with deduction. When I last left the discussion, the biggest issue in my opinion was concept map dropping. The workaround made the deduction algorithm intimidatingly complex.

The following program generates the expected code and runs correctly.
 auto f = [&] <typename T, typename U> (T n, T const& m, U u) { i = ++n; j = 
u(++n); k = ++n; };

This is exciting. The main thing I failed to add was dependent type support, so I want to check this out. (I need to register a new ssh key)

- John

Reply via email to