Der Compiler sagt mir, dass ich versuche, auf eine gelöschte Funktion (d. h. den Kopierkonstruktor eines Lambda-Ausdrucks) zuzugreifen. Aber ich sehe nicht wo.
%Vor% (Ich versuche herauszufinden, warum sie shared_ptr<task>
in Ссылка ) verwenden.
Auf Gcc und MSVC bekomme ich den gleichen Fehler - ich fürchte, ich mache etwas falsches ...
%Vor% Warum kann ich dieses std::function
nicht auf den Vektor setzen?
Von cppreference :
F muss die Anforderungen von Callable und CopyConstructible
erfüllen
Dabei ist F
der Funktionstyp, der zum Erstellen von std::function
verwendet wird. % Co_de% ist jedoch nicht kopierbar . Daher ist std::packaged_task
in der Erfassungsliste nicht kopierbar und ist ein nicht-statisches Mitglied von Lambda, wodurch der implizite Kopierkonstruktor für das Lambda gelöscht wird.
Kurze Antwort: Lambdas und std::packaged_task
sind nicht std::function
s.
Lange Antwort, Sie können ein std::packaged_task
nicht in ein std::function
Hier ist, was ich als Lösung anbiete:
%Vor% Wenn Sie tatsächlich eine std :: -Funktion benötigen und nicht nur irgendeine aufrufbare, müssen Sie ein Lambda in ein std::function
Der Konstruktor von std::function
benötigt das übergebene Funktionsobjekt als CopyConstructible
, aber std::packaged_task<F>
ist nicht (für F
). std::function
führt -Typ löschen durch, wobei der dynamische Typ im statischen Typ nicht sichtbar ist. Betrachten Sie z.B.:
Der Aufruf von invoke
erfordert das Kopieren von f
(pass by value). % Co_de% ist jedoch kopierbar, wenn es aus f
erstellt wurde, aber nicht kopierbar, wenn es aus l
erstellt wurde, und dies hat nichts mit dem statischen Typ von p
zu tun. Es gibt grundsätzlich drei Ansätze für dieses Problem:
f
zur Kompilierzeit ist verboten. std::function
zur Kompilierzeit zulassen, aber einen Laufzeitfehler ausgeben, wenn der enthaltene Typ nicht kopierbar ist. std::function
zur Kompilierzeit und fordern Sie jedes Funktionsobjekt, das Sie kopieren, als kopierbar an. Approach # 1 ist sehr restriktiv in Bezug darauf, wie Funktionen gespeichert, weitergegeben und geteilt werden können, und verbietet im Allgemeinen häufige Anwendungsfälle zugunsten des ungewöhnlichen Falls, ein nicht kopierbares Funktionsobjekt zu verwenden.
Approach # 2 ist problematisch, da die Benutzer darauf hingewiesen werden müssen, dass das Kopieren eines std::function
in einigen Fällen fehlschlagen und beim Schreiben ihres Codes große Sorgfalt walten lassen kann. Wenn das Design Sharing-Funktionen erfordert, müssen sie möglicherweise in eine std::function
eingebunden werden. Und wenn sie kopiert werden müssen und möglicherweise zustandsbehaftet sind, wird es noch schlimmer.
Egal, wie Sie den Ansatz # 3 betrachten, er ist standardisiert. Aber angesichts der oben genannten Probleme ist es auch leicht zu verteidigen.
Tatsächlich habe ich eine std::shared_ptr
-Klassenvorlage geschrieben, die Ansatz Nr. 1 für mein aktuelles Projekt verwendet, weil für uns der Anwendungsfall des Speicherns nicht kopierbarer asynchroner Aufgabenobjekte ziemlich üblich ist und Kopieren oder Teilen von solchen Eine Aufgabe ist nicht notwendig.
Tags und Links c++ vector move-semantics