0

I have a class called Matrix<t>, My professor asked me to write an exception class:

Matrix::IllegalInitialization

Such that it includes the function what(), So I wrote (In Matrix.h):

template<class T>
class Matrix<T>::IllegalInitialization {
public:
    std::string what() const {
        return "Mtm matrix error: Illegal initialization values";
    }
};

But I have a problem that this class doesn't inherit Exceptions, how to fix this?

I want the following to work:

     try {
         Dimensions dim(0,5);
         Matrix<int> mat(dim);
} catch (const mtm::Matrix<int>::IllegalInitialization & e){ cout<< e.what() <<endl;
}

Edit: Is this how should my code look like?

template<class T>
class Matrix<T>::IllegalInitialization : public std::exception {
public:
   const char* what() const override {
      return "Mtm matrix error: Illegal initialization values";
   }
};

I am getting:

error: exception specification of overriding function is more lax than base version

Moia
  • 2,216
  • 1
  • 12
  • 34
  • 3
    Just inherit from `std::exception`? I don't understand the problem – UnholySheep Jun 25 '20 at 09:59
  • Declare `IllegalInitialization` as a nested class of your `Matric` class template. – vahancho Jun 25 '20 at 10:00
  • inheritance is actually not that common in the standard library, but `std::exception` is made to be inherited from, you fix it by inheriting from it – 463035818_is_not_an_ai Jun 25 '20 at 10:00
  • the question is double unclear. First, why cant you just inherit from `std::exception`? And second, "I want the following to work" should already work (also without inheriting from `std::exception`). Please clarify what is your problem – 463035818_is_not_an_ai Jun 25 '20 at 10:01
  • 2
    Please provide a [mcve] and the compiler error if there is one, or explain actual and expected outcome – 463035818_is_not_an_ai Jun 25 '20 at 10:02
  • @idclev463035818 Sorry for the confusion I made, to summarise, how may I inherit std::exception? –  Jun 25 '20 at 10:03
  • 1
    do you know how to inherit `foo` from `bar`? – 463035818_is_not_an_ai Jun 25 '20 at 10:03
  • yes but then I would have class Matrix::IllegalInitialization::public std::exception –  Jun 25 '20 at 10:04
  • @idclev463035818 I am inheriting 3 classes –  Jun 25 '20 at 10:04
  • 1
    there is no inheritance in the code you posted, but anyhow you can inherit from as many classes as you like. What is the problem? – 463035818_is_not_an_ai Jun 25 '20 at 10:05
  • then I should write: Matrix::IllegalInitialization::public std::exception? –  Jun 25 '20 at 10:05
  • @Daniel post a minimal reproducible example. – Moia Jun 25 '20 at 10:06
  • @Daniel thats wrong syntax, but inheriting from `std::exception` is not different than inheriting from any other type. If you have problem with code you should include the code ([mcve]) and the error message – 463035818_is_not_an_ai Jun 25 '20 at 10:06
  • @idclev463035818 updated my question and added what I did, please take a look –  Jun 25 '20 at 10:09
  • Note that your current code *will work* as it is, because you can throw literally anything in C++. Inheriting from `std::exception` is a good practice, but your class already quacks like a duck, which is enough for some uses. – Yksisarvinen Jun 25 '20 at 10:12
  • @Yksisarvinen how it should be for perfect use? plus how to fix the error –  Jun 25 '20 at 10:14
  • What does template class Matrix::IllegalInitialization even means? – Moia Jun 25 '20 at 10:14
  • Have you tried typing your error message into a search engine? https://stackoverflow.com/questions/53829852/exception-specification-of-overriding-function-is-more-lax-than-base-version – UnholySheep Jun 25 '20 at 10:16
  • 1
    Please read about [mcve]. We dont need to see the `Matrix` and the code you posted is incomplete. Trying to compile it will result in errors unrelated to your question – 463035818_is_not_an_ai Jun 25 '20 at 10:18

2 Answers2

2

The what() method of std::exception is (cf cppreference):

virtual const char* what() const noexcept;

Your method is not declared noexcept hence it cannot override std::exception::what().

463035818_is_not_an_ai
  • 109,796
  • 11
  • 89
  • 185
  • I have added noexcept and all works fine, just to summarise is my code well written now? –  Jun 25 '20 at 10:22
  • 1
    @Daniel you need to understand that I cannot tell you if code is correct when I can only see fragments of it. As already mentioned, the code you did post is incomplete and when I would try to compile it I get errors unrelated to your question. In any case, eventually it is always you who has to understand every detail and make sure that the code is correct – 463035818_is_not_an_ai Jun 25 '20 at 10:24
  • @Daniel inheriting from `std::runtime_error` is more convenient, because it already has an implementation of `what` and a constructor that takes the string to be printed – 463035818_is_not_an_ai Jun 25 '20 at 10:27
  • But should const appear at the end or as I wrote it (The const which means *this won't be affected) –  Jun 25 '20 at 10:29
0

This is an example with a little bigger amount of code lines, but it more flexible

Usage example:

try {
    throw MatrixErrors{ErrorCode::kIllegalInitialization};
} catch (const MatrixErrors& error) {
    std::cerr << error.what() << std::endl;
    return 1;
}

The code:

enum class ErrorCode {
  kIllegalInitialization,
};

// Helper function to get an explanatory string for error
inline std::string GetErrorString(ErrorCode error_code) {
  switch (error_code) {
    case ErrorCode::kIllegalInitialization:
      return "Mtm matrix error: Illegal initialization values";
  }
  return {};
}

class MatrixErrors : public std::runtime_error {
 public:
  explicit MatrixErrors(ErrorCode error_code) : std::runtime_error{GetErrorString(error_code)}, code_{error_code} {}

  ErrorCode GetCode() const noexcept { return code_; }

 private:
  ErrorCode code_;
};
sty4
  • 16
  • 3