Pergunta

I was wondering whether it would be possible (through clever conversion rules) to write an "exception" class that would help with the following:

Instead of writing:

try {
 ...
} catch (std::execption const e) {    // StdLib exceptions
} catch (CException* pEx) {           // MFC exceptions
} catch (CORBA::Exception const& e) { // CORBA exceptions
} // note handling code inside catch blocks omitted for brevity

It would be nice if a type could be constructed that would work like so:

try {
  ...
} catch( magic_exception_handle const& e) { // catches all three types mentioned above
  const std::string msg = e.what(); // could also provide generalized message extraction
}

Would this be possible? How?

Note: Other solutions I don't like:

  • I can do catch(...) but I do not want to catch-all.
  • catch-handler function:

    void handler3() {
      try {
        throw;
      } catch (std::execption const e) {    // StdLib exceptions
      } catch (CException* pEx) {           // MFC exceptions
      } catch (CORBA::Exception const& e) { // CORBA exceptions
      } // note handling code inside catch blocks omitted for brevity
    }
    
    ...
    try { ... } catch(...) { handler3(); }
    

    doesn't cut it either, because while any other exception would be thrown outwards, it first would catch any other exception which results in a premature stack unwinding before it is rethrown. (Which is very inconvenient for any resulting crash-dumps on Windows.)

  • I could write a Macro for the catch block. (ugh)

So, is it possible to create a magic_exception_handle type? Has it been done?

Foi útil?

Solução

Your only real option is to invert the logic:

template<typename F, typename... Args>
auto convert_exceptions(F &&f, Args... &&args)
-> decltype(f(std::forward<Args>(args)...)) {
   try {
      return f(std::forward<Args>(args)...));
   } catch (std::exception const e) {    // StdLib exceptions
      std::throw_with_nested(magic_exception{...});
   } catch (CException* pEx) {           // MFC exceptions
      std::throw_with_nested(magic_exception{...});
   } catch (CORBA::Exception const& e) { // CORBA exceptions
      std::throw_with_nested(magic_exception{...});
   }
}

You can now write:

try {
   convert_exceptions([&]() {
      // ...
   });
} catch (const magic_exception &e) {
   // ...
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top