c++ - C+ + - lambda指针捕获的[this]指针在lambda运行之前是否失效?

让我用一个例子来说明:


#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不捕获这个指针,而是某些其他类字段,那么该怎么做?

时间:

C++并不能防止指针失效,而且,就像你所强调的,当向量调整大小时,向量中的对象移动地址,如果你尝试运行lambda,这将导致问题。

所以,如果你尝试捕获this,并且在运行时没有发现问题,这并不意味着你的程序是正确的。

解决方案,我使用std::unique_ptr或std::shared_ptr的智能指针类型来分配对象。

如果复制对象是可能的,则可以通过值捕获*this : (需要C++17 )


return [*this] { somethingToDo(); moreThingsToDo(); }



这会将整个对象复制到闭包中,以避免访问原始对象。

...