У меня есть std::packaged_task
, содержащий лямбду, которая копирует переменную. Когда этот std::packaged_task
будет удален, я ожидаю, что переменная, живущая внутри лямбды, будет уничтожена, но я заметил, что если я получаю связанный std::future
для этого std::packaged_task
, объект future
продлевает время жизни переменной внутри лямбды.
Например:
#include <iostream>
#include <future>
class Dummy
{
public:
Dummy() {std::cout << this << ": default constructed;" << std::endl;}
Dummy(const Dummy&) {std::cout << this << ": copy constructed;" << std::endl;}
Dummy(Dummy&&) {std::cout << this << ": move constructed;" << std::endl;}
~Dummy() {std::cout << this << ": destructed;" << std::endl;}
};
int main()
{
std::packaged_task<void()>* p_task;
{
Dummy ScopedDummy;
p_task = new std::packaged_task<void()>([ScopedDummy](){std::cout << "lambda call with: " << &ScopedDummy << std::endl;});
std::cout << "p_task completed" << std::endl;
}
{
std::future<void> future_result;
{
future_result = p_task->get_future();
(*p_task)();
delete p_task;
}
std::cout << "after p_task has been deleted, the scope of future_result determines the scope of the dummy inside p_task" << std::endl;
}
std::cout << "p_task cleans up when future_result dies" << std::endl;
}
Возможный вывод:
0x7fff9cf873fe: default constructed;
0x7fff9cf873ff: copy constructed;
0x1904b38: move constructed;
0x7fff9cf873ff: destructed;
0x7fff9cf873fe: destructed;
lambda call with: 0x1904b38
after p_task has been deleted, the scope of future_result determines the scope of the dummy inside p_task
0x1904b38: destructed;
p_task cleans up when future_result dies
Таким образом, время жизни объекта внутри лямбды увеличивается на область действия future_result
.
Если мы закомментируем строку future_result = p_task->get_future();
, возможный вывод:
0x7fff57087896: default constructed;
0x7fff57087897: copy constructed;
0x197cb38: move constructed;
0x7fff57087897: destructed;
0x7fff57087896: destructed;
lambda call with: 0x197cb38
0x197cb38: destructed;
after p_task has been deleted, the scope of future_result determines the scope of the dummy inside p_task
p_task cleans up when future_result dies
Мне было интересно, какой механизм здесь задействован, содержит ли std::future
какую-то ссылку, которая поддерживает связанные объекты?