2013-04-06 10 views
9

Con mia sorpresa, ho ricevuto un errore durante il tentativo di utilizzare std::vector::get_allocator() con un allocatore non copiabile. Perché il valore std::vector::get_allocator() restituisce il valore in base al valore e non in base al riferimento?Perché std :: vector :: get_allocator() restituisce per valore?

template<typename T> 
class nc_allocator { 
public: 
    using value_type = T; 

    nc_allocator(nc_allocator const&) = delete; 
    nc_allocator& operator=(nc_allocator const&) = delete; 

    // Other required members. 
}; 

std::vector<int, nc_allocator<int>> v; 
// boom: use of deleted function 
//   'nc_allocator<T>::nc_allocator(const nc_allocator<T>&) [with T = int]' 
v.get_allocator(); 
+2

ho il sospetto che i casi di allocatori dovrebbero essere trattati come maniglie. La prova di ciò è che due allocatori sono considerati uguali solo se uno può cancellare gli oggetti dell'altro. –

risposta

7

ho ottenuto un errore quando si cerca di utilizzare std::vector::get_allocator() con un allocatore non copiabile.

Lo standard vieta di farlo. I requisiti di allocatore in 17.6.3.5 indicano che un allocatore deve essere copiabile.

X a1(a);   Shall not exit via an exception. 
       post: a1 == a 
X a1(move(a)); Shall not exit via an exception. 
       post: a1 equals the prior value 
       of a. 

Quindi il ritorno per valore è un modo corretto di restituire un allocatore, in relazione ai requisiti di allocatore definiti dallo standard.

Non sono sicuro che perché questo è un requisito ma se gli allocatori non calcolabili sarebbero stati consentiti, l'ottimizzazione di base vuota non avrebbe più funzionato.

+0

In senso stretto, ciò dice solo che un'operazione di copia non deve uscire da un'eccezione; non dice che deve essere possibile. –

+2

Dice che questa espressione deve essere valida e questa espressione è esattamente la stessa dei tipi di 'CopyConstructible'. È ancora più forte da quando la copia non deve fare eccezione. – ipc

+0

Non è più forte del testo testuale "il membro get_allocator() restituisce una copia" –

1

Lo standard dettami semplicemente così:

[C++11: 23.2.1/7]:[..] In tutti i tipi di contenitori definite in questo punto, l'organo get_allocator () restituisce una copia del allocatore utilizzato per costruire il contenitore o , se questo allocatore è stato sostituito, una copia della più recente sostituzione [..]

ho il sospetto @ Vaughn corretto nella sua ipotesi che allocatori sono destinate ad essere u sed come "maniglie".

Con molto analogia sciolto, vorresti mai scrivere un funtore non copiabile per l'uso con algoritmi standard?

+4

Ma perché lo standard lo dice? –

+0

@Zoidberg: Perché qualcuno ha deciso che deve. Cercare di razionalizzare il motivo per cui X è stato creato con la proprietà Y è sia non costruttivo che off-topic su Stack Overflow. –

+0

Come si fa questa parte dello standard "se questo allocatore è stato sostituito"? –

Problemi correlati