2011-08-21 4 views

risposta

10

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. `

1

L'allocatore richiede un costruttore di copia perché i contenitori hanno un costruttore di copia e dovranno copiare il loro allocatore nel processo.

+1

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

4

È 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.

+1

Nicol Bolas, sarà OK se allocator (const allocator &) = delete ;? come siamo nel 2016 –

0

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.