什么时候在 lambda 函数中释放变量副本?

When does a variable copy be released in lambda function?

如下例,我定义了2个变量x和y。当我两次调用 lambda 函数时,它似乎不会破坏副本。来自 11.14 — Lambda captures | Learn C++ - Learn C++,它说:

Because captured variables are members of the lambda object, their values are persisted across multiple calls to the lambda!

C++ 如何管理 lambda 函数的内存?

int main() {
    int x = 1;
    static int y = 1;
    auto fun = [=]() mutable{
        x++;
        y++;
        cout<<"Inside:\t\t";
        cout<<"x:"<<x<<"\t"<<"y:"<<y<<endl;
    };

    for (int i = 0; i<2; i++) {
        fun();
        cout<<"Outside:\t";
        cout<<"x:"<<x<<"\t"<<"y:"<<y<<endl<<endl;
    }
}

输出:

Inside:         x:2     y:2
Outside:        x:1     y:2

Inside:         x:3     y:3
Outside:        x:1     y:3

它将它存储在 object 本身中。下面是另一种思考 lambda 的方法。这“有点”等同于编译器生成的内容,是的,我正在稍微改变范围并且我知道这一点,但这对于 C++ 的初学者来说可能更清楚。

static int y = 1; // Moved this out from main
class my_lambda{
public:
my_lambda(int x) : _x(x) {}
~my_lambda() = default;
void operator()()
{
  _x++;
  y++;
  cout<<"Inside:\t\t";
  cout<<"_x:"<<_x<<"\t"<<"y:"<<y<<endl;
}

private:
int _x;
};

int main() {
    int x = 1;
    my_lambda fun{x}; // "Captures" x

    for (int i = 0; i<2; i++) {
        fun();
        cout<<"Outside:\t";
        cout<<"x:"<<x<<"\t"<<"y:"<<y<<endl<<endl;
    }
}

如您所见,我制作的“假 lambda”class 与您的实际 lambda 做的事情相同。它“捕获”x 作为其构造函数的一部分,并将其复制到内部存储,我称之为 _x。 y 只是在它的范围内,尽管我移动到 global 以高于 class 声明。

我正在重载 () 运算符以创建可调用的 class,这在某些情况下是正常的事情。如果您想了解更多信息,请参阅运算符 overloading

这就是 lambda 的“某种程度上”工作方式。他们将您的 body 放入生成的 object 的 operator() 中,捕获的任何内容都是 object 的变量之一,实际的 object(如果按值)或引用,如果以这种方式捕获。

然后 直接 回答你的问题:当 fun 超出范围时,它会被释放,无论是在 lambda 中还是在我的情况下。