2010-08-06 14 views
5

Qualcuno potrebbe spiegare perché sto ricevendo un errore di compilazione qui - errore C2558: classe 'std :: auto_ptr < _Ty>': nessun costruttore di copia disponibile o costruttore di copia è dichiarata 'esplicito'Nessun costruttore di copia disponibile o costruttore di copie dichiarato 'esplicito'

#include <memory> 
#include <vector> 
#include <string> 
template<typename T> 
struct test 
{ 
    typedef std::auto_ptr<T> dataptr; 
    typedef std::auto_ptr< test<T> > testptr; 
    test(const T& data): 
    data_(new T(data)) 
    { 
    }; 
    void add_other(const T& other) 
    { 
     others_.push_back(testptr(new test(other))); 
    } 
private: 
    dataptr data_; 
    std::vector<testptr> others_; 
}; 

int main(int argc, char* argv[]) 
{ 
    test<std::string> g("d"); 

    //this is the line that causes the error. 
    g.add_other("d"); 

    return 0; 
} 
+0

È passato un po 'di tempo da quando ho eseguito C++, ma non dovrebbe essere 'g = test (" d ");'? –

+0

@Jesse J: Entrambi sono ok. I due modi hanno un comportamento leggermente diverso che in tutti tranne i casi più diabolici danno lo stesso risultato. Tecnicamente il tuo metodo creerà una classe di test e poi la assegnerà a g, piuttosto che solo inizializzare g stesso. Questo diventa un problema solo quando si hanno comportamenti personalizzati di copia/assegnazione/init. – Akusete

+0

Grazie a tutti. Risposte davvero istruttive – Carl

risposta

6

Fondamentalmente un std::auto_ptr non può essere utilizzato in questo modo.

others_.push_back(testptr(new test(other))); 

richiede che un costruttore di copia che prende un const& esiste e non esiste una tale costruttore per std::auto_ptr. Questo è ampiamente considerato come dal non si dovrebbe mai usare std::auto_ptr in un contenitore! Se non capisci perché questo è, allora read this article by Herb Sutter, in particolare la sezione intitolata "Cose da non fare, e Perché non farle" circa 3/4 del modo attraverso.

+1

Se i contenitori standard fossero obbligati a usare 'swap' per copiare le cose, auto_ptr funzionerebbe. E vorrei davvero che lo fossero. In C++ 0x, ':: std :: unique_ptr' (che è molto simile a' :: std :: auto_ptr') non ha nemmeno un contructor di copia e ha solo un costruttore di move e i container standard sono obbligatori usare il costruttore di mosse per spostare il loro contenuto, così puoi immagazzinare ':: std :: unique_ptr' in loro e farlo funzionare come previsto. – Omnifarious

+0

In effetti, è illegale usare 'auto_ptr' in un contenitore perché i contenitori STL richiedono che i loro membri abbiano un comportamento di copia" normale ". Auto_ptr non soddisfa questo requisito. –

+1

@Omnifarious: stai mixando shared_ptr con unique_ptr. Shared_ptr è un puntatore intelligente conteggiato di riferimento, non uno con la semantica del movimento. –

4

Non è possibile creare contenitori della libreria standard di auto_ptr, come si sta cercando di fare qui:

std::vector<testptr> others_; 

in quanto non hanno la semantica corretta. Dovrai utilizzare puntatori ordinari o un diverso tipo di puntatore intelligente, ad esempio shared_ptr.

Problemi correlati