Ich habe eine std::packaged_task
mit einem Lambda, die eine Variable durch Kopie erfasst. Wenn dieses std::packaged_task
gelöscht wird, würde ich erwarten, dass die Variable innerhalb des Lambda zerstört wird, aber ich bemerkte, dass, wenn ich das zugehörige std::future
für dieses std::packaged_task
bekomme, das future
Objekt die Lebensdauer der Variable innerhalb des Lambda verlängert.Wie wirkt sich std :: future auf die Lebensdauer einer zugeordneten std :: packaged_task aus?
Zum Beispiel:
#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;
}
Eine mögliche Ausgabe lautet:
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
So das Objekt innerhalb der Lambda hat seine Lebensdauer durch den Umfang der future_result
erweitert.
Wenn wir die Linie future_result = p_task->get_future();
eine mögliche Ausgabe ist auf Kommentar:
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
ich gefragt haben, was Mechanismus hier Spiel kommt in, tut std::future
enthält einige Links, die zugehörigen Objekte am Leben hält?
welchen Compiler benutzen Sie? clang erzeugt die erwartete Ausgabe, dh die Aufgabe wird zerstört, wenn die paketierte Aufgabe ... ist. Ihr Compiler sieht die Aufgabe als Teil des gemeinsamen Status an. Das sieht für mich nicht korrekt aus ... –
Ich benutze gcc 7.2.0. Sie haben recht, cla2ng erzeugt wirklich die zweite Ausgabe. Denkst du, das würde als Fehler gelten? –
ok, [gcc libstdC++ sources] (https://gcc.gnu.org/onlinedocs/gcc-7.2.0/libstdc++/api/a00074_source.html#l01476) zeigt, dass die Aufgabe tatsächlich im Shared-State gespeichert ist. Das scheint mir falsch zu sein, obwohl der Standard das Speichern einer Kopie im Shared-State nicht ausdrücklich verbietet ... nun, mal sehen, was andere sagen ... –