2012-01-24 6 views
6

Mi piacerebbe avere un vettore di unique_ptr come membro di una classe che sto facendo.Come dichiarare un vettore di unique_ptr come membro dati di classe?

class Foo { 
    [...] 

private: 
    vector<unique_ptr<Bar>> barList; 
} 

Ma poi ho iniziare a ricevere i messaggi di errore criptici dal VS2010 compilatore:

error C2248: 'std::unique_ptr<_Ty>::operator =' : cannot access private member declared in class 'std::unique_ptr<_Ty>' 

Insieme a una manciata di righe di errore sotto di quella che tuffarsi implementazione Microsoft di std::_Copy_impl<> ...

Ho modificato la dichiarazione membro in

vector<unique_ptr<Bar>>* barList; 

E compila. Ma non posso fare a meno di chiedermi perché non posso farlo nel modo in cui inizialmente lo volevo? Per sorrisi, ho provato questo e funziona benissimo:

vector<Bar> barList; 

Ma ora perdo la comodità di unique_ptr. Voglio la mia torta e voglio mangiarla anch'io!

+0

stavo guardando http://stackoverflow.com/questions/8553464/vector-as-a-class-member e la risposta sembra pensare dichiarare un 'VECTOR' come ho fatto io è bene fare. Per qualche ragione, però, sembra attivare copie illegali quando si aggiunge la parte 'unique_ptr'. –

+1

Cosa fare il vostro costruttore di copia e l'assegnazione operatore assomigliare? –

+0

incarico privato, ma costruttore di copia era il colpevole. Passato da 'unique_ptr' a' shared_ptr' quando ho capito che stavo usando la proprietà semantica sbagliata. –

risposta

10

Il problema qui è che da qualche parte, il codice sta tentando di chiamare l'operatore "copia-assegnazione" di .

Questo fa sì che il compilatore tenti di generare un operatore di assegnazione delle copie che chiama gli operatori di copia-assegnazione di tutti i sottooggetti di Foo. Alla fine, questo porta a un tentativo di copiare un unique_ptr, un'operazione che non è possibile.

+0

Grazie per aver segnalato questo. Il compilatore mi ha ingannato perché l'errore faceva riferimento alla dichiarazione del membro e non faceva menzione del codice che causa la copia. Immagino che questa sia una carenza di VS2010 e, si spera, migliorerà con le versioni più recenti. La mia classe 'Foo' ha un costruttore di copie, e stavo cercando di copiare il vettore dal sorgente' Foo'. La proprietà condivisa sembra essere la soluzione migliore, quindi passare a 'shared_ptr' ha funzionato. –

+1

Sembra un bug in VS2010 ottengo questo errore anche se il mio codice non cerca mai di chiamare copia-assigment. Disabilitare l'operatore = con dichiarazione come privato (quindi = eliminazione non supportata) risolve il problema. – tr3w

-2

Non è possibile utilizzare unique_ptr in vettoriale poiché l'implementazione vettoriale si basa fortemente sui valori assegnati all'operatore, che è privato in unique_ptr. Usa shared_ptr da boost o altra implementazione smart ptr da C++ 11.

+6

'unique_ptr' funziona perfettamente in un' vector'. [Vedi.] (Http://ideone.com/riLhp) –

+0

C++ 11 contenitori sono tenuti a lavorare con il movimento di sola tipi come 'unique_ptr'. – bames53

+0

Intendevo il modo in cui lo usava. Ma ancora, grazie, non sapevo di emplace_back. – aambrozkiewicz

4

unique_ptr non ha semantica della copia, quindi non è possibile utilizzare alcun metodo per copiare l'oggetto contenuto. È possibile possibile fare questo con riferimenti di rvalue utilizzando std::move nel luogo (s) sta cercando di fare una copia. Senza vedere il tuo codice non posso dire dove sarebbe.

Se compila nel secondo modulo o non hai esercitato lo stesso codice o c'è un bug del compilatore. Entrambi dovrebbero fallire allo stesso modo.

Il terzo esempio, la memorizzazione per valore è il modo più semplice a meno che gli oggetti non siano grandi e costosi da archiviare/copiare in base al valore.

+1

'auto_ptr' è quello che non obbedisce alla semantica della copia normale,' unique_ptr' semplicemente non ** ha ** copia semantica – Grizzly

+0

Le risposte di Your e Mankarse sono molto simili. La sua, però, mi ha fatto capire che avevo bisogno di andare in una caccia alle streghe per il codice incriminato (la risposta affrontato tale questione in modo più sottile). Entrambi meritate la risposta accettata, però. Grazie per l'aiuto! –

2

Spesso uno std::move(iUniquePtr) manca (ad esempio quando si utilizza push_back).

0

Un brani tratti da www.cplusplus.com

std::unique_ptr::operator= 

assegnazione unique_ptr L'oggetto acquista la proprietà dei contenuti di x, che comprende sia il puntatore memorizzato ed il deleter memorizzato (insieme con la responsabilità di eliminare l'oggetto ad un certo punto). Qualsiasi oggetto di proprietà dell'oggetto unique_ptr prima che la chiamata venga cancellata (come se fosse stato chiamato il distruttore di unique_ptr).

Ma c'è un avvertimento troppo:

Questa pagina descrive una funzionalità introdotta con l'ultima revisione del C++ standard (2011). I compilatori precedenti potrebbero non supportarlo.

MSVC 2010 definisce operator= come privato (non copiabile) ma supporta il metodo swap.

Problemi correlati