Lambda implicit capture fails with variable declared from structured binding

后端 未结 2 392
梦谈多话
梦谈多话 2020-11-28 10:45

With the following code, I get a compile error C2065 \'a\': undeclared identifier (using visual studio 2017):

[] {
    auto [a, b] = [] {return          


        
相关标签:
2条回答
  • 2020-11-28 11:34

    Core issue 2313 changed the standard so that structured bindings are never names of variables, making them never capturable.

    P0588R1's reformulation of lambda capture wording makes this prohibition explicit:

    If a lambda-expression [...] captures a structured binding (explicitly or implicitly), the program is ill-formed.

    Note that this wording is supposedly a placeholder while the committee figures out exactly how such captures should work.

    Previous answer kept for historical reasons:


    This technically should compile, but there's a bug in the standard here.

    The standard says that lambdas can only capture variables. And it says that a non-tuple-like structured binding declaration doesn't introduce variables. It introduces names, but those names aren't names of variables.

    A tuple-like structured binding declaration, on the other hand, does introduce variables. a and b in auto [a, b] = std::make_tuple(1, 2); are actual reference-typed variables. So they can be captured by a lambda.

    Obviously this is not a sane state of affairs, and the committee knows this, so a fix should be forthcoming (though there appears be some disagreement over exactly how capturing a structured binding should work).

    0 讨论(0)
  • 2020-11-28 11:35

    A possible workaround is to use a lambda capture with the initializer. The following code compiles fine in Visual Studio 2017 15.5.

    [] {
        auto[a, b] = [] {return std::make_tuple(1, 2); }();
        auto r = [a = a] {return a; }();
    }();
    
    0 讨论(0)
提交回复
热议问题