Home > Net >  Can't multiply two matrices, where hight and width are defined by template
Can't multiply two matrices, where hight and width are defined by template

Time:11-29

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 current input), thereby making it non-template, or

  • you 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.
  • Related