Algunos código de alto nivel será genéricamente simplemente ponerse std::exception
e imprimir el what()
. Desea exprimir la mayor cantidad de información posible a este mecanismo genérico, pero sin perder información. Considere una implementación de alguna biblioteca de archivos:
archive::archive(const char* filename)
{
ifstream file(filename)
file.exceptions(ios_base::badbit);
open_archive(file); // throws ios_base::failure, or some other low-level exception.
}
La información disponible para el archivo no está grabada (por ejemplo, nombre de archivo). Además, le gustaría distinguir las excepciones que provienen de la clase de archivo de otras excepciones.
archive::archive(const char* filename)
{
try {
ifstream file(filename)
file.exceptions(ios_base::badbit);
open_archive(file); // throws ios_base::failure, or some other low-level exception.
} catch(const std::exception& e) {
throw archive_exception("Can't open archive", filename, e.what());
}
}
Ahora añade la información semántica de alto nivel que archive
clase sabe, pero también pierde la información sobre la causa original del problema (del tipo de e
). nested_exception
está destinado a resolver este problema:
archive::archive(const char* filename)
{
try {
ifstream file(filename)
file.exceptions(ios_base::badbit);
open_archive(file); // throws ios_base::failure, or some other low-level exception.
} catch(...) {
throw_with_nested(archive_exception("Can't open archive", filename));
}
}
Toda la información disponible se registra. Podemos ahora genéricamente recuperamos en el sitio de captura:
void print_exception_info(const std::exception& e)
{
cerr << e.what() << "\n";
try {
rethrow_if_nested(e);
} catch(const std::exception& ne) {
print_exception_info(ne);
} catch(...) { }
}
int main() {
try {
run();
} catch(const std::exception& e) {
print_exception_info(e);
}
}
la salida será más descriptivo que antes. Se describirá el problema a partir del alto nivel para el bajo nivel:
no puede abrir archivo "my_archive.bin"
Acceso denegado.
O quizás:
no puede abrir archivo "my_archive.bin"
Record 'aabb' not found.
Las funciones que trabajan con exception_ptr
están diseñadas para transferir excepciones entre hilos, o más generalmente, almacenar una excepción para un uso posterior. Cómo funcionan depende de la implementación. La intención era que exception_ptr
sea un puntero compartido para el objeto de excepción. Sin embargo, cuando se crea este puntero, al lanzar la excepción o al intentar obtener un exception_ptr
, está sujeto a la implementación. La implementación aún puede copiar la excepción cuando llame al current_exception()
.
Una buena (la mejor?) Descripción está disponible en la norma. Puede leer el último [borrador disponible públicamente] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf) de forma gratuita. – ybungalobill