Catch Multiple Custom Exceptions? - C++

前端 未结 7 1449
我在风中等你
我在风中等你 2020-12-24 10:44

I\'m a student in my first C++ programming class, and I\'m working on a project where we have to create multiple custom exception classes, and then in one of our event handl

7条回答
  •  慢半拍i
    慢半拍i (楼主)
    2020-12-24 11:02

    I had a similar problem today, but it turned out I didn't need my solution to solve my problem. Honestly, I couldn't think of real use cases (logging?), and I didn't find much use for it in my code.

    Anyway, this is an approach with type lists (requires C++11). I think the advantage of this approach is that there's no need to have a common base class for custom exceptions (except for std::exception, maybe?). In other words, it is not intrusive to your exception hierarchy.

    There might be some subtle errors that I am not aware of.

    #include 
    #include 
    
    /// Helper class to handle multiple specific exception types
    /// in cases when inheritance based approach would catch exceptions
    /// that are not meant to be caught.
    ///
    /// If the body of exception handling code is the same
    /// for several exceptions,
    /// these exceptions can be joined into one catch.
    ///
    /// Only message data of the caught exception is provided.
    ///
    /// @tparam T  Exception types.
    /// @tparam Ts  At least one more exception type is required.
    template 
    class MultiCatch;
    
    /// Terminal case that holds the message.
    /// ``void`` needs to be given as terminal explicitly.
    template <>
    class MultiCatch {
     protected:
      explicit MultiCatch(const char* err_msg) : msg(err_msg) {}
      const char* msg;
    };
    
    template 
    class MultiCatch : public MultiCatch {
      static_assert(std::is_base_of::value, "Not an exception");
    
     public:
      using MultiCatch::MultiCatch;
    
      /// Implicit conversion from the guest exception.
      MultiCatch(const T& error) : MultiCatch(error.what()) {}  // NOLINT
    
      /// @returns The message of the original exception.
      const char* what() const noexcept {
        return MultiCatch::msg;
      }
    };
    
    /// To avoid explicit ``void`` in the type list.
    template 
    using OneOf = MultiCatch;
    
    /// Contrived example.
    void foo() {
      try {
        bar();  // May throw three or more sibling or unrelated exceptions.
      } catch (const OneOf& err) {
        log() << "External failure: " << err.what();
    
        throw;  // Throw the original exception.
      }
    }
    

提交回复
热议问题