I wrote Class Matrix, parameters of which I define by template. So when I tried to declare operator* between two matrices, I found out? that Cpp counts matrices with different parameters as different classes (For example 7x3 and 3x5). How can I avoid this?
Here is my class
template <size_t N, size_t M, typename T = int64_t>
class Matrix {
public:
Matrix();
Matrix(std::vector<std::vector<T>> const input);
Matrix(const T elem);
Matrix operator (const Matrix& other) const;
Matrix& operator =(const Matrix& other);
Matrix operator-(const Matrix& other) const;
Matrix& operator-=(const Matrix& other);
Matrix operator*(const T& other) const;
Matrix& operator*=(const T& other);
Matrix operator*(const Matrix& other) const;
Matrix& operator*=(const Matrix& other);
Matrix Transposed();
T Trace();
T& operator()(const size_t i, const size_t j) const;
bool operator==(const Matrix& other) const;
private:
};
Cppref did not helped :(
CodePudding user response:
Template arguments are part of the type; otherwise they couldn't be considered in type resolution and SFINAE. Thus, there are two choices:
either make
N, M
runtime arguments of e.g.Matrix
(or can even be deduced from currentinput
), thereby making it non-template, oryou live with the fact that the concrete class depends on
N, M
and, optionally, you might have a base class where this part of the type is erased; or, if you don't need a common base type, you might have the operator as a template and then you might have a different Matrix on the rhs.
The latter can be like this:
typename<T = int64_t>
class Matrix {
Matrix();
Matrix(std::vector<std::vector<T>> const input);
Matrix(const T elem);
// other operators, functions
virtual Matrix operator*(const Matrix& other) const;
};
template <size_t N, size_t M, typename T = int64_t>
class FixedSizeMatrix : Matrix<T> {
// as now, possibly with override when appropriate
Matrix<N, M1> operator*(const Matrix& other) const override /* final? */;
};
However, this will be slower, due to virtual resolution. If you don't need a common base:
template <size_t N, size_t M, typename T = int64_t>
class Matrix {
public:
// as before
template<size_t N1, size_t M1, typename T2 = int64_t>
Matrix operator*(const Matrix<N1, M1, T2>& other) const;
};
Main question to ask yourself is, why you want `N, M` to be compile-time arguments.