gpt4 book ai didi

c++ - lambda 捕获的 [this] 指针可以在 lambda 运行之前失效吗?

转载 作者:行者123 更新时间:2023-12-02 01:21:26 25 4
gpt4 key购买 nike

假设我们有一个STL容器,里面有一些对象,这些对象可以将函数发布到队列中以便稍后执行。但在执行这些函数之前,容器会被修改,使得指向该对象的指针无效。让我用一个例子来说明:

#include <vector>
#include <functional>
class Class_A
{
public:
std::function<void()> getFunctionToRunLater()
{
return [this] () { somethingToDo(); moreThingsToDo(); };
// Returns a lambda function that captures the this pointer,
// so it can access the object's methods and variables.
}

void somethingToDo();
void moreThingsToDo();
}

int main()
{
std::vector<Class_A> vec;
vec.push_back(Class_A());

std::function<void()> pendingFunction = vec.back().getFunctionToRunLater();

// More code...

pendingFunction();
}

一切都很好,对吧?我们得到一个对象想要运行的函数,经过一些逻辑后,我们执行该函数。这表示将函数发布到队列,并且它们执行队列中的所有函数。但现在看看这个:

int main()
{
std::vector<Class_A> vec;
vec.push_back(Class_A());

std::function<void()> pendingFunction = vec.back().getFunctionToRunLater();

// More code...

vec.reserve(1000);
// This will surely reallocate the vector, invalidating all pointers.

pendingFunction();
// And now my program is going straight down to hell, right?
}

我的假设正确吗?如果 lambda 根本没有捕获任何内容,会发生什么情况,程序在逻辑上还会被破坏吗?如果 lambda 不捕获 this 指针,而是专门捕获其他一些类字段,又会怎样呢?

最佳答案

existing answer已经提到指针可以失效。避免该问题的一种方法是,如前所述,通过 shared_ptrunique_ptr 或拷贝更改 *this 的所有权。然而,这需要额外的成本(动态分配或额外的拷贝),有时根本不可能(不可复制的类型)。

相反,我建议一种首先不会导致此问题的设计,即不使 this 指针成为 lambda 状态的一部分。将对象作为参数:

std::function<void(Class_A&)> getFunctionToRunLater()
{
return [] (Class_A& obj) { obj.somethingToDo(); obj.moreThingsToDo(); };
}

关于c++ - lambda 捕获的 [this] 指针可以在 lambda 运行之前失效吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58257802/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com