On 10/01/2020 10:57 AM, John W. Eaton
wrote:
On
10/1/20 1:24 PM, Rik wrote:
In one sense, this is easy to resolve.
Instead of using the keyword "auto" just specify the exact type
of the underlying variable. However, the compiler really should
be able to handle this construct. Could you try 'g++
--version'? And is it really GNU g++ or is this a soft link to
clang?
It looks like accepting auto in this context is a C++14 feature.
Also, I noticed we can simplify some things. The unwind_action
allows writing things like
int val; // Will be captured by the unwind_action objects
below.
unwind_action act ([val] () { use_val (val); })
or
unwind_action act ([] (int val) { use_val (val); }, val);
in the first case, VAL is captured directly by the lambda
_expression_ and is not passed as an argument to the function it
creates. In the second, the unwind_action object captures the
value and passes it as an argument to the function that the lambda
_expression_ creates.
Both forms have the same ultimate effect, but the second is useful
when you want to capture a value that is not directly available as
a variable and can't be captured by the lambda. For example, in
octave::unwind_action restore_warning_state
([] (const octave_value_list& old_warning_state)
{
set_warning_state (old_warning_state);
}, set_warning_state ("Octave:classdef-to-struct", "off"));
the warning state is only accessible through function calls in
this context, so we can't capture it directly in the [] part of
the lambda _expression_, but in other places, we could write
octave::unwind_action close_outfile
([outfile] () { std::fclose (outfile); });
instead of
octave::unwind_action close_outfile
([] (const auto file_ptr) { std::fclose (file_ptr); },
outfile);
Using either form should work but maybe we should use the direct
lambda capture form when the values we need to capture are
variables accessible in the current scope?
"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. I then coded the rest of the lambda
expressions using the same template; perhaps that was lazy of me.
In any case, it's worth paying attention to the variable that is
getting passed and not bother with passing a pointer by reference as
that will merely create a double indirection. Maybe the compiler
would get rid of that, but it's better not to rely on that.
--Rik
|