Re: error with d28016d16e9a (change to jsonencode.cc)
Rik <[email protected]> Thu, 1 Oct 2020 17:13:04 -0700
| Newsgroups | gmane.comp.gnu.octave.maintainers |
|---|---|
| Message-ID | <MTAwMDAwMC5ub21hZA.1601597590@quikprotect> |
On 10/01/2020 12:42 PM, John W. Eaton wrote:
> On 10/1/20 2:33 PM, Rik wrote:
>
>> "should work", but needs to be checked. The first lambda expression I
>> wrote for Octave would not work with capture which is why I used the
>> parameter-passing approach.
>
> Do you remember what it was that didn't work?
I don't. It might work now that we've switched to unwind_action rather
than unwind_protect objects.
>
> Except for "this", lambdas capture by value by default. Capturing "this"
> allows access to the current object, so instead of writing
>
> unwind_action restore_scope
> ([] (auto self) { self->pop (); }, this);
>
> we can write
>
> unwind_action restore_scope ([this] (void) { pop (); });
>
> and instead of
>
> unwind_action executing_callbacks_cleanup
> ([] (auto old_callback_props, auto &self)
> { old_callback_props->erase (self); }, &executing_callbacks, this);
>
> we can write
>
> unwind_action executing_callbacks_cleanup
> ([this] () { executing_callbacks.erase (this); });
>
> In this last case, "executing_callbacks" is also a file-scope static
> variable, so the lambda can access it directly without capture.
I like these as even simpler, less verbose forms.
>
> We could also decide to always use "[=]" when we need to capture
> something. Then all variables that are needed, including "this" will be
> captured using the default rules for capture by value.
I don't think this is recommended practice. The temporary anonymous struct
that is created to represent the lambda expression will then have an
argument in the constructor for every existing variable in the surrounding
function. The compiler *might* then optimize out all of the additional
unused captures, but I think it would be better to just capture what you
need either by value "[=variable_name]" if small like a built-in type or a
pointer or by reference "[&variable_name]" if it is something large like
the instance of a class. For reference, I was using this
https://dzone.com/articles/all-about-lambda-functions-in-cfrom-c11-to-c17.
>
> The unwind_action + lambda expression feature is definitely complicated
> and has a lot of options for how to use it. There's no one right way.
> I'd just like to agree on a set of guidelines to make it as simple as
> possible to write, understand, and maintain. My first pass at that would be
>
> * when possible, capture variables by value directly in the lambda
> expression instead of the unwind_action object
I would modify this to only small values should be passed by value.
>
> * use lambda expression arguments and capture values in the
> unwind_action object only when necessary (for example, when the value is
> not a variable in the local scope)
This seems like a good convention to adopt.
>
> and possibly
>
> * use "[=]" to capture local variables and avoid the redundancy of
> explicitly writing the list of captured variables since they will already
> appear in the lambda expression anyway
I would skip this as noted above.
--Rik
>
> and, once we can move to C++14, maybe also add
>
> * use "auto" for lambda expression argument declarations
>
> jwe
>
>
>