compiler c++ exception c++11 throw noexcept

compiler - Diferencia entre el especificador C++ 03 throw() C++ 11 noexcept



c++11 compiler (3)

Los especificadores de excepciones se desaprobaron porque los especificadores de excepciones generalmente son una idea terrible . noexcept fue agregado porque es el uso razonablemente útil de un especificador de excepción: saber cuándo una función no lanzará una excepción. Por lo tanto, se convierte en una opción binaria: funciones que lanzarán y funciones que no lanzarán.

se agregó noexcept lugar de simplemente eliminar todos los especificadores de tiro distintos de throw() porque noexcept es más poderoso. noexcept puede tener un parámetro que compile-time resuelve en booleano. Si boolean es verdadero, entonces el noexcept pega. Si boolean es falso, entonces el noexcept no se pega y la función puede arrojarse.

Por lo tanto, puedes hacer algo como esto:

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

¿ CreateOtherClass arroja excepciones? Podría, si el constructor predeterminado de T puede. ¿Cómo lo contamos? Me gusta esto:

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

Por lo tanto, CreateOtherClass() lanzará iff arroja el constructor predeterminado del tipo dado. Esto soluciona uno de los principales problemas con los especificadores de excepciones: su incapacidad para propagarse en la pila de llamadas.

No puedes hacer esto con throw() .

¿Hay alguna otra diferencia entre throw() y noexcept aparte del tiempo de ejecución comprobado y el de compilación, respectivamente?

El artículo de Wikipedia C ++ 11 sugiere que los especificadores de lanzamiento de C ++ 03 están en desuso.
¿Por qué es así, pero no es noexcept suficientemente capaz para cubrir todo eso en tiempo de compilación?

[Nota: He referido esta pregunta y este artículo , pero no pude obtener la razón sólida de desaprobación.]


std :: unexpected () es invocado por el tiempo de ejecución de C ++ cuando se infringe una especificación de excepción dinámica: se emite una excepción desde una función cuya especificación de excepción prohíbe las excepciones de este tipo.

std :: unexpected () también se puede llamar directamente desde el programa.

En cualquier caso, std :: unexpected llama al estándar std :: unexpected_handler actualmente instalado. El estándar std :: unexpected_handler llama a std :: terminate.


noexcept no se comprueba en tiempo de compilación.

Una implementación no rechazará una expresión simplemente porque cuando se ejecute arrojará o podría lanzar una excepción que la función contenedora no permite.

Cuando una función que se declara noexcept o throw() intenta lanzar una excepción, la única diferencia es que una llama a terminate y la otra llama a unexpected y el último estilo de manejo de excepciones ha sido desaprobado.