什么时候在 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 中还是在我的情况下。
如下例,我定义了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 中还是在我的情况下。