从左侧将一个常数与一个对象相乘 [英] Multiplying an object with a constant from left side
问题描述
我有一个 Matrix
类,它具有重载的 *
运算符,用于标量和矩阵乘法.
I have a Matrix
class and it has overloaded *
operators for scalar and matrix multiplications.
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;
}
// ...
我可以从右侧将标量与矩阵对象相乘而没有任何问题:
I can multiply a matrix object with a scalar from right side without any problem:
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
但是,如何以相同的方式从左侧将其相乘?
But, how do I multiply it from left side same way?
Matrix<double> X(3, 3, /* ... */);
Matrix<double> Y;
Y = 10.0 * X;
在算术中,在进行乘法运算时在左侧写常量是一种常见的表示法.我想遵守此规则,以使我的代码更具可读性.
In arithmetic, it is a common notation to write constants on the left side when doing multiplication. I would like to obey this rule to make my code more readable.
可以在C ++中实现吗?
如果可能,如何在代码中修改类方法?
Is it possible to implement this in C++?
If it is possible, how do I modify the class method in my code?
推荐答案
成员函数由其左侧参数this指针匹配.由于本机类型不能具有成员函数,因此您必须通过非成员函数(以及其他您没有写权限的类型)与用户定义的类型添加右乘法.
Member functions are matched by their left-hand-side argument which is the this-pointer. Since native types can't have member functions, you have to add right-multiplication with user-defined types through non-member functions (and also for other types you don't have write-access to).
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 Matrix元素实现这些乘法.
NOTE: I wrote the above non-member operator*
implemented in terms of a member operator*=
. It is recommended to write all multiplications as non-member functions, and use a member operator*=
to implement these multiplications with a lhs Matrix element.
这将a)保持类接口最小化,并且b)防止隐藏的转换.例如.如果尺寸为1x1,则可以有一个可以隐式转换为标量的Matrix类,如果不提供直接匹配的单独重载,则这些转换可能会悄无声息地发生.
This will a) keep the class interface minimal, and b) prevent hidden conversions. E.g. you could have a Matrix class that is implicitly convertible to scalar if the dimensions are 1x1, and these conversions could silently happen if you don't provide a separate overload that is a direct match.
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如何是副本而不是引用的通知.这使编译器可以进行优化,例如复制省略/移动语义.还要注意,这些运算符的返回类型为 Matrix< T>
,而不是某些旧的C ++书籍中建议的 const Matrix< T>
C ++ 11.
Notice on how the lhs Matrix is a copy and not a reference. This allows the compiler to make optimizations such as copy elision / move semantics. Also note that the return type of these operators is Matrix<T>
and not const Matrix<T>
which was recommended in some old C++ books, but which prevents move semantics in 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;
}
这篇关于从左侧将一个常数与一个对象相乘的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!