[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
lambda expressions (was: Re: error with d28016d16e9a ...)
From: |
John W. Eaton |
Subject: |
lambda expressions (was: Re: error with d28016d16e9a ...) |
Date: |
Fri, 2 Oct 2020 08:23:33 -0400 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.11.0 |
On 10/1/20 8:13 PM, Rik wrote:
On 10/01/2020 12:42 PM, John W. Eaton wrote:
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.
As I understand it, the lambda expression only captures variables that
are used. Using a capture default specification actually seems better
to me because the variables are already listed in the lambda expression,
so explicitly listing them again is redundant. To me, this seems quite
similar to using "auto" to avoid writing out something that the compiler
can figure out. I don't know why the article you linked lists [=] and
[&] as not recommended. I didn't see an explanation and I'm not finding
other similar recommendations.
* 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.
For unwind-protect to work to save and restore values, they must be
copied. You can't just store a reference to a value that you want to
restore later. See the attached example.
In Octave, most values are reference counted and relatively cheap to
copy anyway.
OTOH, if you mean to use references to objects that are expensive to
copy and that are needed in by the lambda expression but that aren't
there to be saved/restored, then I agree, it's OK to capture by
reference. In that case, it would be nice if you could capture by const
reference so you could explicitly say that you won't be modifying the
value inside the lambda expression, but I don't see a way to do that
without using C++14 features (see
https://en.cppreference.com/w/cpp/language/lambda and search for "This
also makes it possible to capture by const reference").
Note that
unwind_action ([] (const auto& x) { use (x); }, x);
is not capturing X by const reference. The unwind_action object only
captures by value (copy). Then, when the unwind_action destructor
executes, it passes the captured value to the function generated by the
lambda expression by const reference. But the unwind_action object
still grabbed a copy of X.
The following does capture X by reference
unwind_action ([&x] () { use (x); });
but it is not const, so it is possible to change to X in the lambda
expression function and affect the value of X in the parent scope as well.
jwe
lambda-tst.cc
Description: Text Data
Re: error with d28016d16e9a (change to jsonencode.cc), Benjamin Abbott, 2020/10/01
Message not available
Re: error with d28016d16e9a (change to jsonencode.cc), Carlo De Falco, 2020/10/01