2014-12-14 11 views
8

Der Code unten kompiliert und funktioniert wie erwartet. Die Struktur (Klasse) A stammt von std::thread und erweitert sich mit einem int mehr. Der main-Code erstellt einige Threads und wartet anschließend darauf, sie zu beenden.Fehler: Verwendung der gelöschten Funktion 'Std :: Thread :: Thread (Const Std :: Thread &)'

Das Problem ist, dass während der Code ohne destructor kompiliert in struct A, wenn die destructor uncommented (~A(){}) ist erhalte ich:

error: use of deleted function ‘std::thread::thread(const std::thread&)'

und ich habe keine Ahnung, warum.

Darüber hinaus verstehe ich nicht, warum der Code sowohl mit push_back als auch mit emplace_back funktioniert, während nach dem, was ich verstehe, sollte es nicht mit push_back arbeiten.

#include <iostream> 
#include <thread> 
#include <vector> 

struct A : std::thread { 
    int i; 
    A(void f(const char*),const char* s,int i_) : std::thread{f,s},i{i_}{ 
     std::cout<<"A created"<<std::endl; 
    } 
    //~A(){} // uncomment to see error 
}; 

void dosomething(const char* s){ 
    std::cout<<s<<std::endl; 
} 

int main(){ 
    std::vector<A> aa; 
    aa.emplace_back(&dosomething,"hi people",3434); 
    aa.push_back(A(&dosomething,"hi again people",777)); 
    aa.emplace_back(&dosomething,"hi again people",777); 
    aa.push_back(A(&dosomething,"hi again people",777)); 

    for(auto& i:aa) i.join(); 
} 
+0

Welche Compiler-Version und Optionen? Ich bin misstrauisch, dass es sich um einen Compiler Bug handeln könnte. – cdhowie

+0

Warum es mit 'push_back' funktioniert, glaube ich, dass Ihre Struktur' A' für die automatische Generierung eines Move-Konstruktors geeignet ist, also 'push_back' wäre move - konstruiert das' A' im Vektor aus dem temporären, das Sie übergeben (Beachten Sie, dass es eine 'push_back (value_type &&) 'Überladung gibt!) – cdhowie

+0

-g; -O0; -Wall; -std = C++ 14; -thread sowohl mit g ++ und clang ++ als auch -std = c + +11 – user3723779

Antwort

9

Wenn Sie die destructor möchten, können Sie Ihren Code beheben, indem

Zugabe
A(A &&) = default; 

die implizite Bewegung Ctor wieder einzusetzen.


Ihr erstes Problem besteht darin, dass das Hinzufügen der benutzerdefinierten destructor impliziten Erzeugen des Konstruktor Bewegung sperrt.

Der (irreführende) Fehler, den Sie sehen, ist, dass die STL versucht, auf Kopierarten zurückzugreifen, die nicht verschoben werden können, und fehlschlägt, weil std::thread absichtlich nicht kopierbar ist.

Sehen Sie diese cppreference page 's Abschnitt über den implizit deklarierten Move Constructor, und diese other question für einige verwandte Motivation.

Die zweite Quelle der Verwirrung ist, dass push_back eine Bewegung überlastet hat, so dass Ihr ursprünglicher Code nie an erster Stelle kopiert wurde, nur in Bewegung. Wenn Sie dies beweisen wollen, kommentieren Sie das dtor zurück, damit es wieder funktioniert, und versuchen Sie dann, push_back eine const Referenz zu A. Es wird sich über den Kopierkonstruktor beschweren, was bedeutet, dass die anderen push_back-Aufrufe das nicht verwenden.

Verwandte Themen