2013-09-06 12 views
40

Sembra che un vettore verificherà se il costruttore di movimento è etichettato come non eccezionale prima di decidere se spostare o copiare elementi durante la riallocazione. Il costruttore di mosse predefinito è definito noexcept? Ho visto la seguente documentazione ma non ha specificato questo. http://en.cppreference.com/w/cpp/language/move_constructorIl costruttore di spostamento predefinito è definito come noexcept?

costruttore mossa Implicitamente-dichiarato

Se nessuna mossa definita dall'utente costruttori sono forniti per un tipo di classe (struct, di classe, o unione), e tutte le seguenti condizioni: ci sono non esistono costruttori dichiarati dall'utente operatori non ci sono operatori di assegnazione copia dichiarati dall'utente non ci sono operatori di assegnazione di spostamento dichiarati dall'utente non ci sono distruttori dichiarati dall'utente il costruttore di mosse implicitamente dichiarato è non definito come eliminato a causa di condizioni dettagliate nella prossima sezione quindi il compilatore dichiarerà un costruttore di mosse come membro pubblico in linea membro della sua classe con la firma T :: T (T & &) Una classe può avere costruttori di movimento multipli, ad es. sia T :: T (const T & &) e T :: T (T & &). Se alcuni costruttori di spostamento definiti dall'utente sono presenti, l'utente può ancora forzare la generazione del costruttore di spostamento implicitamente dichiarato con la parola chiave predefinita.

risposta

48

Penso che la risposta è 15,4/14 (specifiche eccezione):

un costruttore di ereditare (12.9) ed un implicitamente dichiarata funzione di membro speciale (clausola 12) hanno un specifica delle eccezioni. Se f è un costruttore di ereditare o un costruttore di default implicitamente dichiarato, costruttore di copia, mossa costruttore, distruttore, copia operatore di assegnazione, o spostare operatore di assegnazione, la sua implicita specifica delle eccezioni specifica il tipo-id T se e solo se T è consentito dalla specifica exception di una funzione direttamente richiamata dalla definizione implicita di f; f consente tutte le eccezioni se qualsiasi funzione invoca direttamente consente tutte le eccezioni e f ha la specifica exceptionnoexcept(true) se ogni funzione invocata direttamente non consente eccezioni.

Fondamentalmente, ciò che si pensa, e il costruttore di spostamento implicitamente dichiarato è noexcept ogni volta che può essere.

+29

Ulteriori informazioni: E si può verificare se le vostre aspettative sono state soddisfatte: 'static_assert (std :: :: is_nothrow_move_constructible valore " MyType dovrebbe essere noexcept MoveConstructible");' –

+0

Così tutte le funzioni invocate dalla speciale implicita le funzioni membro devono essere dichiarate 'noxcept' per le funzioni di membro speciale implicite come' noexcept'. Significa che devi essere abbastanza diligente per contrassegnare tutte le funzioni rilevanti 'noxcept', significa che c'è molto spazio per errori umani, giusto? – mucaho

+1

@mucaho: Beh, se tutti i membri stessi usano solo membri speciali definiti in modo implicito, non è poi così complesso. La semplice regola è la regola della singola responsabilità e, per impostazione predefinita, l'unico errore umano a cui prestare attenzione è definire esplicitamente le funzioni membro speciali.Questo lascia solo le classi di scopo speciale (come 'unique_ptr') che è necessario controllare. –

Problemi correlati