Si dice che è a causa delle specifiche delle eccezioni here. Non lo capisco. Questa domanda ha qualche relazione con le specifiche delle eccezioni?perché l'allocatore in C++ ha bisogno di un costruttore di copie?
risposta
Dopo aver letto il tutorial mi sono un po 'confuso dal testo. Ma io credo che sia semplice come questo: il tutorial stava spiegando il motivo per cui intestazione modello del allocatore mostra
allocator(const allocator&) throw();
e
template <class U> allocator(const allocator<U>&) throw();
anche se il costruttore di copia è abbastanza inutile per un allocatore. E la risposta è stata che la specifica di un allocatore non consente al costruttore di generare eccezioni. Pertanto, l'interfaccia pubblica del costruttore di copie definisce i costruttori di copie con una specifica di eccezione di throw()
(non genera eccezioni) per impedire a qualcuno di derivare il proprio allocatore con i costruttori di copia che potrebbero generare un'eccezione.
Vedere this link per una buona descrizione di cosa sia una specifica di eccezione se è questo che ti ha lanciato. (No pun intended.)
Quindi, non significava che quando si crea un allocatore, è necessario fornire un costruttore di copie. Stavano solo sottolineando che la specifica vieta in modo specifico di definire uno che genera eccezioni. `
L'allocatore richiede un costruttore di copia perché i contenitori hanno un costruttore di copia e dovranno copiare il loro allocatore nel processo.
È necessario scrivere esplicitamente un costruttore di copia (anziché utilizzare il valore predefinito) poiché è necessario definire il costruttore di copie per un allocatore C++ 03 con l'identificatore di eccezione throw()
. Il costruttore di copie predefinito non ha questo identificatore.
Tecnicamente, non si dispone di , ma se si genera un'eccezione ... beh, buona fortuna con quello.
Ma questo è solo un fastidio minore, poiché gli allocatori in C++ 03 non possono avere lo stato. Quindi non dovresti copiare membri in giro. Il costruttore di copie può essere vuoto.
Nicol Bolas, sarà OK se allocator (const allocator &) = delete ;? come siamo nel 2016 –
In realtà è piuttosto semplice. Il costruttore di un contenitore che utilizza un allocatore prende l'allocatore e ne memorizza una copia. Per fare ciò, è necessario che l'allocatore sia CopyConstructible
. È tutto. Si noti che un tipo di allocatore non è richiesto per CopyAssignable
a meno che il suo tratto propagate_on_container_copy_assignment
sia vero (che è raro).
La specifica C++ 11 afferma inoltre che "Nessuna operazione di costruzione, confronto operatore, operazione di copia, spostamento o scambio su questi tipi deve uscire da un'eccezione." Le regole di eccezione consentono di effettuare una copia (stack) di un allocatore (in particolare durante la costruzione o la distruzione) senza preoccuparsi che la copia che l'allocatore genererà. Progettare contenitori che siano sicuri per le eccezioni in presenza di allocatori che potrebbero generare copie, spostamenti, scambi o confronti è quasi impossibile. In pratica, un allocatore non può contenere molto più di un puntatore a qualche risorsa, quindi consentire agli allocatori di eseguire copie, ecc., Aggiungerebbe molto dolore senza praticamente alcun guadagno.
Prima di C++ 11, gli allocatori erano necessariamente senza stato. Di conseguenza, è sufficiente chiamare il costruttore predefinito.Post C++ 11, indipendentemente dal fatto che gli allocatori siano copiati dai rispettivi contenitori che li racchiudono in una determinata circostanza, è determinato dalla presenza e dalla definizione dei metodi allocatori 'select_on_container_X_Y'. Vedere il [riferimento dei tratti allocator] (http://en.cppreference.com/w/cpp/memory/allocator_traits) – apmccartney