Предположим, что у нас есть контейнер 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?
}
Правильно ли мое предположение? Что произойдет, если лямбда вообще ничего не захватывает, будет ли программа по-прежнему логически повреждена? А что, если лямбда не захватывает указатель this, а, скорее, какое-то другое поле класса?