2012-02-06 6 views
13

C'è un motivo per cui lo unique_ptr::reset non ha sovraccarichi che richiedono un valore const deleter& e deleter&& in modo che corrisponda ai suoi costruttori che accettano quelli come secondo argomento?Perché unique_ptr :: reset non ha sovraccarichi che richiedono un deleter?

La deleteria memorizzata in unique_ptr verrebbe copiata o spostata assegnata con l'argomento da reset. Se il deleter è noncopyable o nonmovable, la chiamata del sovraccarico corrispondente del reset non verrà compilata. Sembra che sarebbe un comportamento coerente con i costruttori.

risposta

24

ho pensato di aggiungere che, ma si può ottenere la funzionalità equivalente con un operatore di assegnazione mossa:

ptr = unique_ptr<T, D>(new T(another_value), D(another_state)); 

così ho optato per non aver detto la stessa cosa con reset nell'interesse di mantenere l'API ragionevolmente piccolo.

Aggiornamento

E io vivo e imparo ...

La sintassi può effettivamente essere molto più semplice di quello che faccio vedere sopra:

ptr = {new T(another_value), D(another_state)}; 
+3

+1 per avere l'unica risposta _authoritative_ a una domanda "perché". – ildjarn

+0

Non sarebbe più pulito e più coerente con shared_ptr se esistesse una funzione di reset? Per me, è particolarmente pulito quando si dispone di una funzione di cancellazione personalizzata. Ad esempio: 'ptr = unique_ptr (new_raw_ptr, deleter_function);' vs 'ptr.reset (new_raw_ptr, deleter_function);'. O meglio ancora se potessimo mantenere lo stesso deleter_function, quindi sarebbe come: 'ptr.reset (new_raw_ptr);'. – felipou

+1

@felipou: quest'ultimo funziona.Per il primo, ecco come * tu * puoi farlo accadere: http://cplusplus.github.io/LWG/lwg-active.html#submit_issue –

3

Poiché il deleter viene memorizzato nell'oggetto in costruzione. Siccome il tipo deleter è un argomento template, dopo la costruzione non c'è modo di "convertire" la classe in modo da usarne un'altra.

+0

Quindi, richiamare l'operatore di assegnazione di copia o spostare rispettivamente l'operatore di assegnazione. Se il tuo deleter non ha uno accessibile accettabile, non verrà compilato. – David

+0

Non è che l'overengineering di una classe che serve per uno scopo semplice? –

+0

È possibile copiare il costrutto e spostare il costrutto: perché aggiungere la possibilità di copiare assegnare e spostare assegnare è eccessivamente ingegnerizzato? Questo mi sembra un livello di complessità coerente con le altre funzionalità per me (vale a dire, per nulla complesso) – David