2011-12-06 15 views
24

Me he dado cuenta de que hay algunas declaraciones más interesantes en <exception> en C++ 11. ¿Alguien puede arrojar algo de luz sobre lo que significan y cómo usarlos?¿Hay alguna buena descripción de :: std :: nested_exception y amigos?

Los que yo estoy preguntando acerca son:

  1. ::std::nested_exception
  2. ::std::throw_with_nested
  3. ::std::rethrow_if_nested

Además, mientras que parecen explica por sí mismo, que sería bueno saber cómo estos funcionaron:

  1. ::std::exception_ptr
  2. ::std::make_exception_ptr
  3. ::std::current_exception
  4. ::std::rethrow_exception
+1

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

Respuesta

22

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().

+1

No parecería 'print_exception_info' algo así como' try {std :: rethrow_if_nested(); } catch ... '? – Cubbi

+0

En general, he estado reservando lugares para rellenar la excepción de bajo nivel en mis excepciones de alto nivel cuando quiero hacer esto. Pero puedo ver cómo este mecanismo genérico es mejor ya que puedes tener un controlador muy genérico que lo desenrolla todo. – Omnifarious

+0

Tomé prestado gran parte de su ejemplo para [cppreference.com] (http://en.cppreference.com/w/cpp/error/exception/nested_exception) - no dude en modificar ese wiki si desea eliminar o mejorarlo. – Cubbi

Cuestiones relacionadas