Из вашей декларации
template <typename T, size_t r, size_t c> //r=rows,c=cols of the Matrix
class Matrix {
public:
template <size_t L>
Matrix<T, r, L> operator*(const Matrix<T, c, L> &other) const;
template <size_t r, size_t c> // BEWARE: shadowing
Matrix &operator=(const Matrix<T, r, c> &other);
// ...
};
мы можем догадаться, что произойдет.
Matrix<double, 1, 4> m1(1.2);
Matrix<double, 4, 1> m2(1.2);
m1 * m2; // (1)
(1)
звонит Matrix<double, 1, 4>::operator*<1>(Matrix<double, 4, 1> const&)
.В результате он имеет тип Matrix<double, 1, 1>
.
Matrix<double, 2, 2> m3;
m3 = /* (2) */ m1 * m2;
(2)
звонки Matrix<double, 2, 2>::operator=<1, 1>(Matrix<double, 1, 1> const&)
.Это проблема.
Решение состоит в том, чтобы operator=
можно было вызывать только с другой матрицей вправо размера:
template <typename T, size_t r, size_t c> //r=rows,c=cols of the Matrix
class Matrix {
public:
template <size_t L>
Matrix<T, r, L> operator*(Matrix<T, c, L> const& other) const;
Matrix &operator=(Matrix const& other);
// ...
};
Вы могли бы дажеразрешить преобразования типов:
template<class U>
Matrix &operator=(Matrix<U, r, c> const& other);
Наконец, вы можете использовать auto
:
Matrix<double, 1, 4> m1(1.2);
Matrix<double, 4, 1> m2(1.2);
auto m3 = m1 * m2; // m3 is Matrix<double, 1, 1>