Accessing lambda capture initialized variable outside the lambda in C++

后端 未结 2 579
青春惊慌失措
青春惊慌失措 2021-01-18 04:34

In C++14/17, how do you access a lambda capture initialized variable outside the scope of the lambda?

Source:

#include 

using namespac         


        
相关标签:
2条回答
  • 2021-01-18 04:58

    A lambda is just a compact definition for an inline-defined struct and an operator() overload on that struct (and for creating an object of that struct's type). Lambda "captures" are just member variables of this struct, initialized by the type's constructor. This is one reason why C++ lambdas have to have syntax for capturing by value vs. by reference.

    But the members variables of the struct are private. And since the compiler-generated struct is largely implementation-defined, it isn't required by the standard to expose those members with those names. The compiler-generated struct could use some other name if it wanted; the compiler would just have to remap the in-lambda usage of those names to reference the members' names.

    So no, lambda captures of any kind cannot be accessed by the world outside of that lambda. If you capture a reference to an object, then its possible for the outside world to access the same object. But you would not be accessing the same reference to that object.

    0 讨论(0)
  • 2021-01-18 05:03

    Just for completeness, depending on the compiler it is technically possible to access the internal members of the lambda, and modify them. Although this is basically taking advantage of an implementation detail, and should never be done. But it does provide some insight into the lambda implementation.

    Here it is in GCC 6.3

    #include <iostream>
    
    using namespace std;
    
    template<typename Lambda>
    struct lambda_member : Lambda
    {
    
        Lambda& f_;
        lambda_member(Lambda& f) : Lambda(f),
            f_(f)
        {}
    
        auto& get_value1()
        {
            return f_.__value1;
        }
    
    };
    
    
    int main(){
        auto test = [value1 =0]() mutable {value1+=1; return value1;};
    
        lambda_member<decltype(test)> lm{test};
    
        std::cout << test() << std::endl;
        std::cout << lm.get_value1() << std::endl;
        lm.get_value1() = 22;
        std::cout << test() << std::endl;
    
    }
    

    Demo

    0 讨论(0)
提交回复
热议问题