Cómo lanzar una excepción de C ++

Tengo una comprensión muy pobre del manejo de excepciones (es decir, cómo personalizar lanzar, probar, detectar declaraciones para mis propios fines).

Por ejemplo, he definido una función de la siguiente manera: int compare(int a, int b){...}

Me gustaría que la función arroje una excepción con algún mensaje cuando a o b es negativo.

¿Cómo debería abordar esto en la definición de la función?

Sencillo:

 #include  int compare( int a, int b ) { if ( a < 0 || b < 0 ) { throw std::invalid_argument( "received negative value" ); } } 

La biblioteca estándar incluye una bonita colección de objetos de excepción integrados que puede lanzar. Tenga en cuenta que siempre debe arrojar por valor y capturar por referencia:

 try { compare( -1, 3 ); } catch( const std::invalid_argument& e ) { // do stuff with exception... } 

Puede tener múltiples declaraciones catch () después de cada bash, para que pueda manejar diferentes tipos de excepciones por separado si lo desea.

También puedes volver a lanzar excepciones:

 catch( const std::invalid_argument& e ) { // do something // let someone higher up the call stack handle it if they want throw; } 

Y para detectar excepciones independientemente del tipo:

 catch( ... ) { }; 

Simplemente agregue el throw donde sea necesario, y try bloquear al llamante que maneja el error. Por convención, solo debe arrojar elementos que se derivan de std::exception , por lo que debe incluir primero.

 int compare(int a, int b) { if (a < 0 || b < 0) { throw std::invalid_argument("a or b negative"); } } void foo() { try { compare(-1, 0); } catch (const std::invalid_argument& e) { // ... } } 

Además, mira en Boost.Exception .

Aunque esta pregunta es bastante antigua y ya se ha respondido, solo quiero agregar una nota sobre cómo hacer un manejo de excepciones adecuado en C ++ 11:

Use std::nested_exception y std::throw_with_nested

Se describe en StackOverflow aquí y aquí , cómo puede obtener un seguimiento de sus excepciones dentro de su código sin necesidad de un depurador o un registro engorroso, simplemente escribiendo un controlador de excepciones adecuado que volverá a generar excepciones anidadas.

¡Ya que puede hacer esto con cualquier clase de excepción derivada, puede agregar mucha información a tal retroceso! También puede echar un vistazo a mi MWE en GitHub , donde una traza inversa se vería así:

 Library API: Exception caught in function 'api_function' Backtrace: ~/Git/mwe-cpp-exception/src/detail/Library.cpp:17 : library_function failed ~/Git/mwe-cpp-exception/src/detail/Library.cpp:13 : could not open file "nonexistent.txt" 

Puede definir un mensaje para lanzar cuando ocurre un cierto error:

 throw std::invalid_argument( "received negative value" ); 

o podrías definirlo así:

 std::runtime_error greatScott("Great Scott!"); double getEnergySync(int year) { if (year == 1955 || year == 1885) throw greatScott; return 1.21e9; } 

Por lo general, tendrías un try ... catch bloques como este:

 try { // do something that causes an exception }catch (std::exception& e){ std::cerr << "exception: " << e.what() << std::endl; }