将对象与左侧的常数相乘
Posted
技术标签:
【中文标题】将对象与左侧的常数相乘【英文标题】:Multiplying an object with a constant from left side 【发布时间】:2013-01-07 02:09:06 【问题描述】:我有一个 Matrix
类,它为标量和矩阵乘法重载了 *
运算符。
template <class T> class Matrix
public:
// ...
Matrix operator*(T scalar) const;
// ...
// ...
template <class T>
Matrix<T> Matrix<T>::operator*(T RightScalar) const
Matrix<T> ResultMatrix(m_unRowSize, m_unColSize);
for (uint64_t i=0; i<m_unRowSize; i++)
for (uint64_t j=0; j<m_unColSize; j++)
ResultMatrix(i, j) = TheMatrix[m_unColSize * i + j] * RightScalar;
return ResultMatrix;
// ...
我可以毫无问题地将矩阵对象与右侧的标量相乘:
Matrix<double> X(3, 3, /* ... */); // Define a 3x3 matrix and initialize its contents
Matrix<double> Y; // Define an output matrix
Y = X * 10.0; // Do the linear operation
但是,我如何以同样的方式从左侧乘以呢?
Matrix<double> X(3, 3, /* ... */);
Matrix<double> Y;
Y = 10.0 * X;
在算术中,在进行乘法运算时,将常数写在左侧是一种常见的表示法。我想遵守这条规则以使我的代码更具可读性。
是否可以在 C++ 中实现? 如果可以,如何修改代码中的类方法?
【问题讨论】:
有可能,但不能使用类方法。 【参考方案1】:成员函数由其左侧参数匹配,即 this 指针。由于本机类型不能具有成员函数,因此您必须通过非成员函数添加与用户定义类型的右乘(以及您没有写入权限的其他类型)。
template<typename T>
Matrix<T> operator*(T const& scalar, Matrix<T> rhs)
// scalar multiplication is commutative: s M = M s
return rhs *= scalar; // calls rhs.operator*=(scalar);
注意:我写了上面的非成员operator*
,以成员operator*=
的形式实现。建议将所有乘法编写为非成员函数,并使用成员operator*=
用 lhs 矩阵元素实现这些乘法。
这将 a) 保持类接口最小化,并且 b) 防止隐藏转换。例如。如果维度为 1x1,您可以拥有一个可隐式转换为标量的 Matrix 类,如果您不提供直接匹配的单独重载,这些转换可能会静默发生。
template<typename T>
Matrix<T> operator*(Matrix<T> lhs, T const& scalar)
return lhs *= scalar; // calls lhs.operator*=(scalar);
template<typename T>
Matrix<T> operator*(Matrix<T> lhs, Matrix<T> const& rhs)
return lhs *= rhs; // calls lhs.operator*=(rhs);
注意 lhs 矩阵是副本而不是参考。这允许编译器进行优化,例如复制省略/移动语义。另请注意,这些运算符的返回类型是 Matrix<T>
,而不是 const Matrix<T>
,这在一些旧的 C++ 书籍中被推荐,但它阻止了 C++11 中的移动语义。
// class member
template<typename T>
Matrix<T>& Matrix<T>::operator*=(Matrix<T> const& rhs)
// your implementation
return *this;
// class member
template<typename T>
Matrix<T>& Matrix<T>::operator*=(T const& scalar)
// your implementation
return *this;
【讨论】:
【参考方案2】:你需要一个非成员函数:
template <typename T>
Matrix<T> operator*(T scalar, Matrix<T> const & matrix)
return matrix * scalar;
非成员运算符重载允许您在任一侧指定任何类型,而成员重载始终获取左侧的对象。
【讨论】:
以上是关于将对象与左侧的常数相乘的主要内容,如果未能解决你的问题,请参考以下文章