¿Hay alguna diferencia entre throw()
y noexcept
además de ser verificado en tiempo de ejecución y tiempo de compilación, respectivamente?
Este artículo de Wikipedia C ++ 11 sugiere que los especificadores de lanzamiento de C ++ 03 están obsoletos.
¿Por qué es lo noexcept
suficientemente capaz de cubrir todo eso en tiempo de compilación?
[Nota: Revisé esta pregunta y este artículo , pero no pude determinar la razón sólida de la desaprobación].
noexcept
puede incurrir en comprobaciones de tiempo de ejecución. La principal diferencia entre ellos es que rompernoexcept
causasstd::terminate
y romperthrow
causasstd::unexpected
. También un comportamiento de desenrollado de pila ligeramente diferente en estos casos.Respuestas:
Los especificadores de excepciones quedaron obsoletos porque los especificadores de excepciones son generalmente una idea terrible .
noexcept
se agregó porque es el único 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 arrojarán y funciones que no lanzarán.noexcept
se agregó en lugar de simplemente eliminar todos los especificadores de lanzamiento que no seanthrow()
porquenoexcept
es más poderoso.noexcept
puede tener un parámetro que en tiempo de compilación se resuelve en un booleano. Si el booleano es verdadero, entonces senoexcept
pega. Si el booleano es falso, entoncesnoexcept
no se pega y la función puede lanzar.Por lo tanto, puede hacer algo como esto:
¿
CreateOtherClass
Lanza excepciones? Podría, siT
el constructor predeterminado puede. ¿Cómo lo contamos? Me gusta esto:Por lo tanto,
CreateOtherClass()
arrojará iff arroja el constructor predeterminado del tipo dado. Esto soluciona uno de los principales problemas con los especificadores de excepciones: su incapacidad para propagarse por la pila de llamadas.No puedes hacer esto con
throw()
.fuente
noexcept
. Nunca usé elthrow()
especificador, nunca y estoy tratando de determinar sinoexcept
realmente proporciona algún beneficio (aparte de la documentación verificada por el compilador).std::terminate
. que es MUCHO PEOR ! el código puede colarse en las versiones que tienen funciones marcadasnoexcept
y en tiempo de ejecución (es decir, en los sitios del cliente) se detectan violaciones. Me refiero a que el compilador garantiza generar código que no arroje excepciones en primer lugar.throws()
, si se lanza una excepción, la pila debe desenrollarse hasta el alcance de esa función (por lo que todas las variables automáticas de la función se destruyen) en cuyo puntoterminate()
se llama (víaunexpected()
). Si se marca una funciónnoexcept
, si se lanza una excepción, se llama a terminar (el desenrollado de la pila es un detalle definido por la implementación).noexcept
no se comprueba en tiempo de compilación.Cuando una función que se declara
noexcept
othrow()
intenta lanzar una excepción, la única diferencia es que uno llamaterminate
y el otro llamaunexpected
y el último estilo de manejo de excepciones ha quedado obsoleto.fuente
throw()
/noexcept
, la verificación del tiempo de compilación asegura que un overrider también lo tenga.std::unexpected()
es llamado por el tiempo de ejecución de C ++ cuando se viola una especificación de excepción dinámica: se lanza una excepción desde una función cuya especificación de excepción prohíbe excepciones de este tipo.std::unexpected()
también se puede llamar directamente desde el programa.En cualquier caso,
std::unexpected
llama al archivo actualmente instaladostd::unexpected_handler
. Lasstd::unexpected_handler
llamadas predeterminadasstd::terminate
.fuente