Ich versuche, eine std::thread
Funktion mit einem Element zu erstellen, die keine Argumente akzeptiert und zurückgibt void
. Ich kann keine Syntax finden, die funktioniert - der Compiler beschwert sich, egal was passiert. Was ist der richtige Weg, um zu implementieren spawn()
, dass ein std::thread
ausgeführtes zurückgegeben wird test()
?
#include <thread>
class blub {
void test() {
}
public:
std::thread spawn() {
return { test };
}
};
c++
multithreading
c++11
abergmeier
quelle
quelle
std::move( std::thread(func) );
ist besser, dastd::thread
es keinen Kopierkonstruktor gibt.std::move
ist in diesem Fall redundant. Wäre dies nicht der Fall und es gäbe keinen Kopierkonstruktor, würde der Compiler trotzdem einen Fehler ausgeben.Antworten:
BEARBEITEN: Wenn Sie Ihre Bearbeitung berücksichtigen, müssen Sie dies folgendermaßen tun:
UPDATE: Ich möchte noch einige Punkte erläutern, von denen einige auch in den Kommentaren besprochen wurden.
Die oben beschriebene Syntax wird in Bezug auf die INVOKE-Definition (§20.8.2.1) definiert:
Eine weitere allgemeine Tatsache, auf die ich hinweisen möchte, ist, dass der Thread-Konstruktor standardmäßig alle an ihn übergebenen Argumente kopiert. Der Grund dafür ist, dass die Argumente möglicherweise den aufrufenden Thread überleben müssen. Das Kopieren der Argumente garantiert dies. Stattdessen, wenn Sie wirklich wollen , um eine Referenz zu übergeben, können Sie ein verwenden
std::reference_wrapper
erstelltstd::ref
.Auf diese Weise versprechen Sie, dass Sie sicherstellen, dass die Argumente weiterhin vorhanden sind, wenn der Thread sie bearbeitet.
Beachten Sie, dass alle oben genannten Dinge auch auf
std::async
und angewendet werden könnenstd::bind
.quelle
std::thread
Konstruktors mit mehreren Argumenten funktioniert so, als ob die Argumente an übergeben würdenstd::bind
. Um eine Mitgliedsfunktion aufzurufen, muss das erste Argumentstd::bind
ein Zeiger, eine Referenz oder ein gemeinsam genutzter Zeiger auf ein Objekt des entsprechenden Typs sein.bind
? Ich kann das nirgendwo finden.Da Sie C ++ 11 verwenden, ist Lambda-Ausdruck eine schöne und saubere Lösung.
da
this->
weggelassen werden kann, könnte es verkürzt werden auf:oder nur
quelle
std::move
wenn Sie eine lokale Variable nach Wert zurückgeben. Dies hemmt tatsächlich RVO. Wenn Sie nur nach Wert (ohne Verschieben) zurückkehren, verwendet der Compiler möglicherweise RVO, und wenn dies nicht der Fall ist, muss er laut Standard die Verschiebungssemantik aufrufen.[=]
. Damit können Sie versehentlich ein riesiges Objekt kopieren. Im Allgemeinen ist es ein Code-Geruch zu verwenden[&]
oder[=]
.[&]
) verwenden, können Sie Fehler wie einige baumelnde Referenzen einführen. (Zum Beispielstd::thread spawn() { int i = 10; return std::thread( [&] { std::cout<<i<<"\n"; } ); }
)Hier ist ein vollständiges Beispiel
Das Kompilieren mit g ++ führt zu folgendem Ergebnis
quelle
delete
die Erinnerung vom Haufen :)@ hop5 und @RnMss schlugen vor, C ++ 11-Lambdas zu verwenden. Wenn Sie sich jedoch mit Zeigern befassen, können Sie diese direkt verwenden:
Ausgänge
Ein umgeschriebenes Beispiel aus dieser Antwort wäre dann:
quelle
Einige Benutzer haben ihre Antwort bereits gegeben und sehr gut erklärt.
Ich möchte noch ein paar Dinge hinzufügen, die mit Thread zu tun haben.
Wie man mit Funktor und Faden arbeitet. Bitte beziehen Sie sich auf das folgende Beispiel.
Der Thread erstellt beim Übergeben des Objekts eine eigene Kopie des Objekts.
Ein anderer Weg, um dasselbe zu erreichen, ist wie folgt:
Wenn Sie das Objekt jedoch als Referenz übergeben möchten, verwenden Sie die folgende Syntax:
quelle