2012-10-11 16 views
78

C'è qualche altra differenza tra throw() e noexcept oltre al controllo del runtime e del tempo di compilazione rispettivamente?Differenza tra C++ 03 throw() specificatore C++ 11 noex

Wikipedia C++11 articolo suggerisce che gli specificatori di lancio C++ 03 sono deprecati.
Perché così, è noexcept abbastanza in grado di coprire tutto ciò al momento della compilazione?

[Nota: ho fatto riferimento this question e this article, ma non ha potuto ottenuto il motivo solido di deprecazione.]

+6

Per questo [bell'articolo] (http://akrzemi1.wordpress.com/2011/06/10/using-noexcept/) anche 'noexcept' può incorrere in controlli di runtime. La principale differenza tra loro è che l'interruzione di 'noxcept' causa' std :: terminate' mentre l'interruzione di 'throw' causa' std :: unexpected'. In questi casi anche un comportamento di svolgimento leggermente diverso. – Fiktik

risposta

101

prescrittori di eccezione sono stati deprecati a causa exception specifiers are generally a terrible idea. noexcept è stato aggiunto perché è l'unico uso ragionevolmente utile di uno specificatore di eccezioni: sapere quando una funzione non genera un'eccezione. Diventa quindi una scelta binaria: funzioni che getteranno e funzioni che non getteranno.

noexcept è stato aggiunto anziché rimuovere tutti gli identificatori di lancio diversi da throw() perché noexcept è più potente. noexcept può avere un parametro che compila in tempo risolve in un booleano. Se il valore booleano è true, le spille noexcept. Se il valore booleano è falso, lo noexcept non si attacca e la funzione può essere lanciata.

Così, si può fare qualcosa di simile:

struct<typename T> 
{ 
    void CreateOtherClass() { T t{}; } 
}; 

Does CreateOtherClass generano eccezioni? Potrebbe, se il costruttore predefinito di T può. Come lo diciamo? Come questo:

struct<typename T> 
{ 
    void CreateOtherClass() noexcept(is_nothrow_default_constructible<T>::value) { T t{}; } 
}; 

Così, CreateOtherClass() getteranno se e solo se il costruttore predefinito del tipo specificato getta. Questo risolve uno dei problemi principali con gli specificatori di eccezioni: la loro incapacità di propagare lo stack di chiamate.

Non è possibile farlo con throw().

+0

+1 Risposta utile, per me comunque. Sto ancora cercando una risposta che dice perché vorrei usare 'noxcept'. Non ho mai usato l'identificatore 'throw()', mai e sto tentando di determinare se 'noexcept' fornisce effettivamente alcun vantaggio (oltre alla documentazione verificata dal compilatore). – hmjd

+0

Ho appena trovato questo http://stackoverflow.com/questions/10787766/when-should-i-really-use-noexcept ... – hmjd

+0

@hmjd: "* Sto ancora cercando una risposta che dice perché vorrei usare noex . * "Non troverai una risposta a questo qui perché questa * non è la domanda * che è stata posta. –

29

noexcept non viene controllato in fase di compilazione.

Un'implementazione non deve rifiutare un'espressione solo perché quando viene eseguita genera o può generare un'eccezione che la funzione di contenimento non consente.

Quando una funzione dichiarata noexcept o throw() tentativi di un'eccezione l'unica differenza è che si chiama terminate e le chiamate othe unexpected e il secondo lo stile di gestione delle eccezioni è stato efficace deprecato.

1

std :: unexpected() viene chiamato dal runtime C++ quando viene violata una specifica di eccezione dinamica: viene generata un'eccezione da una funzione la cui specifica eccezione proibisce eccezioni di questo tipo.

std :: unexpected() può anche essere chiamato direttamente dal programma.

In entrambi i casi, std :: imprevisto chiama lo std :: unexpected_handler attualmente installato. Il default std :: unexpected_handler chiama std :: terminate.

Problemi correlati