2014-12-14 17 views
8

Il codice muggito compila e funziona come previsto. La struttura (classe) A deriva da std::thread e si espande con uno int in più. Il codice main crea alcuni thread e in seguito li attende per terminare.errore: uso della funzione eliminata 'std :: thread :: thread (const std :: thread &)'

Il problema è che, mentre il codice viene compilato senza un distruttore in struct A, quando il distruttore è commentata (~A(){}) ottengo:

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

e non ho idea sul perché.

Inoltre non capisco perché il codice funzioni entrambi con push_back e con emplace_back mentre in base a ciò che ho capito non dovrebbe funzionare con push_back.

#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

Quale versione del compilatore e opzioni? Sono sospettoso che potrebbe trattarsi di un bug del compilatore. – cdhowie

+0

Per quanto riguarda il motivo per cui funziona con 'push_back', credo che la tua struct' A' sia idonea per la generazione automatica di un costruttore di move, quindi 'push_back' sarebbe move-costruendo il' A' nel vettore dal temporaneo che si passa . (Si noti che c'è un sovraccarico di 'push_back (value_type &&)!) – cdhowie

+0

-g; -O0; -Wall; -std = C++ 14; -pthread entrambi usando g ++ e clang ++ e usando anche -std = c + +11 – user3723779

risposta

9

Se si desidera che il distruttore, è possibile correggere il codice con l'aggiunta di

A(A &&) = default; 

di ripristinare il movimento ctor implicita.


tuo primo problema è che l'aggiunta del distruttore definito dall'utente disattiva generazione implicito della movimento costruttore.

L'errore (fuorviante) che viene visualizzato è il tentativo di STL di ricadere su tipi di copia che non possono essere spostati e in mancanza perché std::thread è volutamente non copiabile.

Vedere la sezione cppreference page sul costruttore di spostamento Implicitamente dichiarato, e questo other question per alcune motivazioni correlate.

La seconda fonte di confusione è che push_back ha un sovraccarico di spostamento, quindi il codice originale non è mai stato copiato in primo luogo, solo in movimento. Se vuoi provarlo, commenta il dtor di nuovo in modo che funzioni di nuovo, quindi prova a push_back un riferimento const a uno A. Si lamenterà del costruttore di copie, il che significa che le altre chiamate push_back non lo utilizzano.

Problemi correlati