I have a template Matrix class:
template <typename T, int row, int col>
class Matrix{};
Inside the class decleration I wrote an execption class, based on std::exception:
class MatrixException: public std::exception
{
private:
const char* errmsg;
public:
MatrixException(const char* msg="")
:errmsg(msg) {}
const char* what() const noexcept {return errmsg;}
};
class IllegalOperation: public MatrixException
{
public:
IllegalOperation(const char* msg="")
: MatrixException(msg) {}
};
I tried to use it on one of the non-class' functions, in the implantation part, like this:
template <typename T, int row1, int col1, int row2, int col2>
Matrix<T, row1, col2> operator*(const Matrix<T, row1, col1>& mat1, const Matrix<T, row2, col2>& mat2)
{
if (condition)
throw Matrix<T, row2, col2>::IllegalOperation("message");
// do stuff
return res;
}
I got a warning:
In instantiation of 'Matrix<T, row1, col2> operator*(const Matrix<T, row, col>&, const Matrix<T, row2, col2>&) [with T = int; int row1 = 3; int col1 = 3; int row2 = 3; int col2 = 2]': required from here
And this error message:
dependent-name 'Matrix<T, row, col>::IllegalOperation' is parsed as a non-type, but instantiation yields a type
How can I fix this?
I've looked here:
Where and why do I have to put the "template" and "typename" keywords?
and then tried to add the word template
here and there, but it didn't work.
You should add typename
keyword to the throw
expression.
if (condition)
throw typename Matrix<T, row2, col2>::IllegalOperation("message");
// do stuff
As stated here
In a declaration or a definition of a template, including alias template, a name that is not a member of the current instantiation and is dependent on a template parameter is not considered to be a type unless the keyword typename is used or unless it was already established as a type name, e.g. with a typedef declaration or by being used to name a base class.
Hence IllegalOperation
in this case is not considered to by a type, but rather is considered probably as a function.