设计Matrix类时的表达式模板问题求助
问题分析与修复方案
问题根源
你的代码无法直接用Matrix C = <表达式>初始化的核心原因是:Matrix类没有提供从表达式模板类型(如AddExp)到Matrix的转换构造函数。编译器无法自动将AddExp对象转换为Matrix对象,而auto会直接推导为表达式类型,因此可以正常运行,但这不是你需要的Matrix实例。
修复步骤
- 给Matrix添加模板转换构造函数:接受任意表达式类型,在构造时遍历表达式求值,填充矩阵元素。
- 确保表达式类的
operator()为const:因为转换构造函数会调用表达式的求值方法,需要保证表达式对象是可const访问的。 - 调整赋值运算符(可选):可以复用转换构造函数的逻辑,处理已有对象的赋值操作。
修正后的关键代码
Matrix类添加转换构造函数
template <typename T, size_t Rows, size_t Cols> class Matrix { private: T data[Rows][Cols]{}; public: // 默认构造函数 Matrix() = default; // 模板转换构造函数:接受任意表达式类型 template <typename Exp> Matrix(const Exp& exp) { for (size_t i = 0; i < Rows; ++i) { for (size_t j = 0; j < Cols; ++j) { data[i][j] = exp(i, j); } } } // 元素访问运算符 T& operator()(size_t i, size_t j) { return data[i][j]; } const T& operator()(size_t i, size_t j) const { return data[i][j]; } // 赋值运算符:复用表达式求值逻辑 template <typename Exp> Matrix& operator=(const Exp& exp) { for (size_t i = 0; i < Rows; ++i) { for (size_t j = 0; j < Cols; ++j) { data[i][j] = exp(i, j); } } return *this; } };
修正AddExp的operator()为const
template <typename Lhs, typename Rhs> class AddExp { private: const Lhs& lhs; const Rhs& rhs; public: AddExp(const Lhs& lhs_, const Rhs& rhs_) : lhs(lhs_), rhs(rhs_) {} // 改为const成员函数,支持const表达式对象的访问 auto operator()(size_t i, size_t j) const { return lhs(i, j) + rhs(i, j); } };
保持加法运算符的实现
template <typename Lhs, typename Rhs> AddExp<Lhs, Rhs> operator+(const Lhs& lhs, const Rhs& rhs) { return AddExp<Lhs, Rhs>(lhs, rhs); }
验证效果
现在可以正常使用Matrix<int,3,3> C = A + B;这样的写法,编译器会通过转换构造函数将AddExp表达式求值后转换为Matrix对象,同时避免了临时Matrix对象的创建,符合表达式模板的设计初衷。
内容的提问来源于stack exchange,提问作者Quasar
相关产品推荐
相关产品推荐

