c++ - Capturing a Lambda's static in a Nested Lambda -
in this answer use code:
std::vector<std::vector<int>> imat(3, std::vector<int>(10)); std::for_each(imat.begin(), imat.end(), [&](auto& i) { static auto row = 0; auto column = 0; std::transform(i.begin(), i.end(), i.begin(), [&](const auto& /*j*/) { return row * column++; }); ++row; });
but notice misbehavior in capturing static auto row
depending upon compiler.
0 0 0 0 0 0 0 0 0 0
0 1 2 3 4 5 6 7 8 9
0 2 4 6 8 10 12 14 16 18
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
and visual studio 2015 gives me compile time error:
an internal error has occurred in compiler.
if change capture nested capture capture row
explicitly compiler error:
identifier in capture must variable automatic storage duration declared in reaching scope of lambda
am allowed capture static
in nested lambda? seems legit, there many problems!
edit:
fozi pointed out can visual studio 2015 compile , give same output clang 3.7.0 if change nested lambda's parameter type const auto&
const int&
. seems unrelated, works.
this doesn't work if try capture row
explicitly. in case still compiler error:
identifier in capture must variable automatic storage duration declared in reaching scope of lambda
i've reported visual studio 2015 bug here: https://connect.microsoft.com/visualstudio/feedback/details/1930409/capturing-a-lambdas-static-in-a-nested-lambda
an internal compiler error(ice) bug.
we don't need capture variables of static storage duration need capture automatic variables odr-used. draft c++ standard section 5.1.2
:
the lambda-expression’s compound-statement yields function-body (8.4) of function call operator, but purposes of name lookup (3.4), determining type , value of (9.3.2) , transforming idexpressions referring non-static class members class member access expressions using (*this) (9.3.1), the compound-statement considered in context of lambda-expression.
so row
should visible within inner lambda and:
[...]if lambda-expression or instantiation of function call operator template of generic lambda odr-uses (3.2) or variable automatic storage duration reaching scope, entity shall captured lambda-expression.[...]
capture required this
, variables of automatic storage duration if odr-used , can see explicit capture defined automatic variables or this:
the identifier in simple-capture looked using usual rules unqualified name lookup (3.4.1); each such lookup shall find entity. entity designated simple-capture said explicitly captured, and shall or variable automatic storage duration declared in reaching scope of local lambda expression.
for both visual studio , gcc match results of clang can move row
out global namespace, see live gcc. fozi points out changing const auto& /*j*/
const int& /*j*/
makes start working.
it looks gcc accepts explicit capture of non-automatic variables extension , explicitly capturing row
example [&, &row](const auto & )
still produces zeros.
further gcc if move definition row
main
see following error (see live):
/tmp/cchzwtqi.s: assembler messages: /tmp/cchzwtqi.s:1572: error: symbol `_zl3row' defined
which seems compiler error me.
i don't see portion of standard make original program ill-formed. nor should changing auto
int
make difference , non of changes introduced polymorphic lambda proposal seem explain difference either.
Comments
Post a Comment