模板类实现矩阵乘法的编译错误排查求助
矩阵乘法编译错误的解决方案
错误原因与修正步骤
1. 构造函数维度初始化颠倒
原构造函数里m_cols(rows), m_rows(cols)完全搞反了行和列的对应关系,应该改为m_rows(rows), m_cols(cols),否则矩阵的维度逻辑彻底错误,后续的乘法维度检查、元素访问都会出问题。
2. 乘法运算符模板参数非法
原operator*写法中用int作为模板参数的实参,违反了C++非类型模板参数必须是编译期常量的规则。矩阵乘法要求左矩阵的列数等于右矩阵的行数,因此需要给右操作数新增一个模板参数r_cols(表示右矩阵的列数),让返回矩阵的维度为rows × r_cols。
3. 缺失必要的成员函数
代码中用到了size()和operator()但未实现,必须补充这两个基础函数才能让矩阵类正常工作:
size():返回矩阵的总元素数operator():重载用于访问矩阵元素(需要普通版本和const版本,分别支持修改和读取)
修正后的完整代码
矩阵类实现
#include <stdexcept> template<class T, int rows, int cols> class matrix { private: T m_data[rows * cols]; int m_rows; int m_cols; public: // 修正行/列初始化顺序的构造函数 matrix() : m_rows(rows), m_cols(cols) { for (int i = 0; i < rows * cols; i++) m_data[i] = T(); // 调用数据类型的默认构造函数初始化元素 } // 拷贝构造函数 matrix(const matrix& other) : m_rows(other.m_rows), m_cols(other.m_cols) { for (int i = 0; i < other.size(); i++) m_data[i] = other.m_data[i]; } // 返回矩阵总元素数 int size() const { return m_rows * m_cols; } // 重载():非const版本,用于修改元素 T& operator()(int row, int col) { // 可选:添加越界检查 if (row < 0 || row >= m_rows || col < 0 || col >= m_cols) { throw std::out_of_range("Matrix index out of bounds"); } return m_data[row * m_cols + col]; } // 重载():const版本,用于读取元素 const T& operator()(int row, int col) const { if (row < 0 || row >= m_rows || col < 0 || col >= m_cols) { throw std::out_of_range("Matrix index out of bounds"); } return m_data[row * m_cols + col]; } // 补充set函数(用户代码中用到) void set(int row, int col, const T& value) { (*this)(row, col) = value; } // 修正后的乘法运算符:新增模板参数r_cols约束右矩阵列数 template<int r_cols> matrix<T, rows, r_cols> operator*(const matrix<T, cols, r_cols>& RHS) const { // 可选运行时检查:模板参数已保证左列数=右行数,保留可提供更友好的错误提示 if (m_cols != RHS.m_rows) { throw std::invalid_argument("Matrix dimensions must match for multiplication!"); } matrix<T, rows, r_cols> toReturn; for (int i = 0; i < rows; ++i) { for (int j = 0; j < r_cols; ++j) { toReturn(i, j) = T(); for (int k = 0; k < cols; ++k) { toReturn(i, j) += (*this)(i, k) * RHS(k, j); } } } return toReturn; } };
测试代码(main函数)
int main() { matrix<int, 2, 2> m1; m1.set(0, 0, 1); m1.set(0, 1, 2); m1.set(1, 0, 3); m1.set(1, 1, 4); matrix<int, 2, 1> m2; m2.set(0, 0, 1); m2.set(1, 0, 1); matrix<int, 2, 1> m3 = m1 * m2; // 验证结果:m3(0,0)=3,m3(1,0)=7 return 0; }
几点重要说明
- 乘法运算符被定义为模板成员函数,通过
r_cols模板参数确保右矩阵的行数与左矩阵的列数一致,同时明确返回矩阵的维度。 - 构造函数的行/列顺序修正后,矩阵的维度逻辑才符合预期。
- 补充的
operator()是矩阵类的核心功能,确保元素访问的正确性;size()则保证拷贝构造函数能正常工作。
内容的提问来源于stack exchange,提问作者Aryan MP
相关产品推荐
相关产品推荐

