使用模板类实现矩阵乘法时出错

  • 本文关键字:出错 实现 c++
  • 更新时间 :
  • 英文 :


我的作业是这样的。我正在努力,并持有相同的初级知识。我必须创建一个包含此代码的头文件,然后使用该头文件来获得所需的结果。

我正在使用c++模板和操作符重载。

#include <iostream>
#include <memory>
#include "matrix.h"
#include "symetric_matrix.h"
using namespace std;
int main()
{
const Matrix<int, 3, 2> m1; // Creates 3*2 matrix, with all the default elements set to 0;
cout << m1 << endl;
Matrix<int, 3, 3> m2(4); // Creates 3*3 matrix, with the default elements equals to 4;
cout << m2 << endl;
const Matrix<int, 3, 3> m3 = m2; // C-py constructor may take O(MN) and not O(1).
cout << m3 << endl;
// min() returns the minimal value in the matrix.
if (min(m1) < min(m3))
cout << "Min value of m3(" << min(m3) << ") is bigger than min value of m1(" << min(m1) << ")" << endl;
if (m1.avg() < m3.avg()) // Compares the average of the elements
cout << "Average value of m3(" << m3.avg() << ") is bigger than average value of m1(" << m1.avg() << ")" << endl;
m2(0, 0) = 13;
cout << m2[0][0] << " " << m2[1][0] << endl; // Should print "13 4"
try
{
cout << m2 + m3 << endl;
cout << m3 * m1 << endl; // You can choose the format of matrix printing;
cout << m1 * m2;         // This should throw an exception
}
catch (const Matrix<int, 3, 2>::IllegalOperation &e)
{
cout << e.what() << endl;
}
Matrix<int, 3, 3> m4;
m4 = m3;
cout << m4 << endl;
for (int i = 0; i < 3; ++i)
for (int j = 0; j < 3; ++j)
m4(i, j) = i + j;
cout << m4 << endl;
cout << "m4[1][1] = " << m4[1][1] << endl;
cout << "m4[1][1] = " << m4(1, 1) << endl; // m4(1,1) same result as m4[1][1]
Matrix<int, 3, 3> m5(3);
m5 = 2 * m4;
cout << m5 << endl;
Matrix<int, 3, 3> m6(m4);
cout << m6 << endl;
m5 += m4;
cout << m5 << endl;
if (m6 != m5)
cout << "m6 != m5" << endl;
Matrix<Matrix<int, 3, 2>, 4, 4> composite(m1); // Creates matrix, where each element is m1;
cout << composite;
unique_ptr<Matrix<int, 3, 3>> symetric_matrix(new SymetricMatrix<int, 3>(5)); // SymetricMatrix matrix 3*3 with default element equals to 5;
(*symetric_matrix)(1, 2) = 8;
cout << (*symetric_matrix)(1, 2) << " " << (*symetric_matrix)(2, 1) << endl; // Should print "8 8"
cout << (*symetric_matrix)[1][2] << " " << (*symetric_matrix)[2][1] << endl; // Should print "8 8"
(*symetric_matrix)[1][0] = 18;
cout << (*symetric_matrix)[1][0] << " " << (*symetric_matrix)[0][1] << endl; // Should print "18 18"
return 0;
}
我的<<p> strong> 解决方案。
template <class T, int M, int N>
class Matrix
{
private:
T mat[M][N];
int rows = M;
int cols = N;
public:
// constructor
Matrix(int v = 0)
{
for (int i = 0; i < M; i++)
{
for (int j = 0; j < N; j++)
mat[i][j] = v;
}
}
T &operator()(int i, int j)
{
return mat[i][j];
};
T *operator[](int index)
{
return mat[index];
};
// << overloading
friend std::ostream &operator<<(std::ostream &os, const Matrix<T, M, N> &L)
{
for (int i = 0; i < M; i++)
{
for (int j = 0; j < N; j++)
os << L.mat[i][j] << " ";
os << "n";
}
return os;
};
template <class T1, int M1, int N1>
Matrix<T, M, M> operator*(Matrix<T1, M1, N1> const &other);
Matrix<T, M, M> operator+(Matrix<T, M, N> const &other);
friend T min(Matrix obj)
{
T result = obj.mat[0][0];
for (int i = 0; i < M; i++)
{
for (int j = 0; j < N; j++)
if (result < obj.mat[i][j])
result = obj.mat[i][j];
}
return result;
};
long double avg() const
{
long double result = 0;
for (int i = 0; i < M; i++)
{
for (int j = 0; j < N; j++)
if (result < mat[i][j])
result = result + mat[i][j];
}
return result / (M * N);
}
};
template <class T, int M, int N>
Matrix<T, M, M> Matrix<T, M, N>::operator+(Matrix const &other)
{
if ((this->rows == other.rows) && (this->cols == other.cols))
{
Matrix<T, M, N> resultantMatrix;
for (auto i = 0; i < this->rows; i++)
{
for (auto j = 0; j < this->cols; j++)
{
auto &valueFirst = this->mat[i][j];
auto &valueSecond = other.mat[i][j];
// if ((additionOverflow(valueFirst, valueSecond)) || (additionUnderflow(valueFirst, valueSecond)))
//     throw std::out_of_range("Resultant value of matrix is out of range");
// else
resultantMatrix(i, j) = valueFirst + valueSecond;
}
}
return resultantMatrix;
}
else
throw std::runtime_error("Matrices cannot be added, sizes do not match");
}
template <class T, int M, int N>
template <class T1, int M1, int N1>
Matrix<T, M, M> Matrix<T, M, N>::operator*(Matrix<T1, M1, N1> const &other)
{
if ((this->rows == other.rows) && (this->cols == other.cols))
{
Matrix<T, M, N> resultantMatrix;
for (auto i = 0; i < this->rows; i++)
{
for (auto j = 0; j < this->cols; j++)
{
for (auto k = 0; k < this->cols; k++)
{
auto &valueFirst = this->mat[i][k];
auto &valueSecond = other(k, j);
// if ((additionOverflow(valueFirst, valueSecond)) || (additionUnderflow(valueFirst, valueSecond)))
//     throw std::out_of_range("Resultant value of matrix is out of range");
// else
resultantMatrix(i, j) += valueFirst * valueSecond;
}
}
}
return resultantMatrix;
}
else
throw std::runtime_error("Matrices cannot be added, sizes do not match");
}

我得到一个错误,我不明白为什么。

error: no match for call to ‘(const Matrix<int, 3, 2>) (int&, int&)’
112 |                     auto &valueSecond = other(k, j);
|                                         ~~~~~^~~~~~
matrix.h:20:8: note: candidate: ‘T& Matrix<T, M, N>::operator()(int, int) [with T = int; int M = 3; int N = 2]’ (near match)
20 |     T &operator()(int i, int j)
|        ^~~~~~~~
matrix.h:20:8: note:   passing ‘const Matrix<int, 3, 2>*’ as ‘this’ argument discards qualifiers

它只发生在这行auto &valueSecond = other(k, j);而不发生在这行resultantMatrix(i, j) += valueFirst * valueSecond;,为什么?

我只是需要帮助整个程序,而我试着学习!如有任何帮助,不胜感激。

对于错误信息

matrix.h:20:8: note:   passing ‘const Matrix<int, 3, 2>*’ as ‘this’ argument discards qualifiers

otherconst Matrix<int, 3, 2>&T &operator()(int i, int j)是为非constMatrix<int, 3, 2>&实现的。应该提供两个版本的操作符

T &operator()(int i, int j)
{
return mat[i][j];
};
const T &operator()(int i, int j) const
{
return mat[i][j];
};
T *operator[](int index)
{
return mat[index];
};
const T *operator[](int index) const
{
return mat[index];
};

使用operator()作为下标操作符可能会引起混淆。应该是

T &operator[](int i, int j)
{
return mat[i][j];
};
const T &operator[](int i, int j) const
{
return mat[i][j];
};

下标操作符通常为size_t类型定义。

最新更新