我实现了这样的模板矩阵类。
template<typename T, int NRows, int NCols>
class MatrixMN;
但是现在我怀疑用模板实现矩阵是正确的选择,原因如下。
operator*=
无法定义这是因为矩阵乘法的 * =运算符可能会返回具有不同维度的矩阵类型。
不同的维度在模板实现中意味着不同的类型。
T
参数让我们为矩阵乘法定义一个二元运算符。
template <typename T1, int NRows1, int NCols1, typename T2, int NRows2, int NCols2>
MatrixMN<??, NRows1, NCols2> operator*(const MatrixMN<T1, NRows1, NCols1> &m1, const MatrixMN<T2, NRows2, NCols2> &m2)
T1
和T2
可能是{int
和double
}或{double
和int
}。
所以我无法决定返回T
的{{1}}参数。
我提出了一些解决方法。
MatrixMN
具有MatrixMN
double
参数定义运算符。但是没有一个能够完美地解决问题......
像这样实现矩阵类是不对的?
答案 0 :(得分:2)
您可以将operator*
限制为仅适用于相同类型的矩阵,并且您知道结果大小:m-by-n乘以n-by-k会得到m-by-k矩阵。把它放在一起就可以了:
template<typename T, int M, int N, int K>
MatrixMN<T, M, K> operator*(const MatrixMN<T, M, N> &lhs, const MatrixMN<T, N, K> &rhs)
如果您只想允许隐式可转换类型,请使用std::common_type
:
// Arithmetic operation allowing for implicitly convertible types
template<typename TL, typename TR, int M, int N, int K>
MatrixMN<typename std::common_type<TL, TR>::type, M, K> operator*(
const MatrixMN<TL, M, N> &lhs,
const MatrixMN<TR, N, K> &rhs)
如果您想允许您定义的任何类型组合,那就是traits
的用途:
template<typename LHS, typename RHS, typename RES>
struct MatrixMNBinaryTraitsBase {
typedef LHS TypeLeft; // Element type of left hand side
typedef RHS TypeRight; // Element type of right hand side
typedef RES TypeMultResult; // Element type of matrix multiplication
};
// Base case: support for implicitly convertible types
template<typename TL, typename TR>
struct MatrixMNBinaryTraits : MatrixMNBinaryTraitsBase<TL, TR, typename std::common_type<TL, TR>::type> { };
// Special case Foo x Bar -> Foobar
template<>
struct MatrixMNBinaryTraits<Foo, Bar> : MatrixMNBinaryTraitsBase<Foo, Bar, Foobar> { };
// Arithmetic operation allowing for different types according to MatrixMNBinaryTraits
template<typename TL, typename TR, int M, int N, int K>
MatrixMN<typename MatrixMNBinaryTraits<TL, TR>::TypeMultResult, M, K> operator*(
const MatrixMN<TL, M, N> &lhs,
const MatrixMN<TR, N, K> &rhs)
答案 1 :(得分:2)
您的运算符可以定义为具有良好维度和良好基础类型的矩阵(即T1
和T2
,以便有效operator*
取T1
和T2
及其类型已定义operator+
。
template <typename T1, typename T2>
using multiply_type = decltype(std::declval<T1>()*std::declval<T2>());
template <typename T1, typename T2, int N, int K, int M>
auto operator*(Matrix<T1, N, K> const& m1, Matrix<T2, K, M> const& m2)
-> Matrix<multiply_type<T1, T2>, M, N> {
/* Implementation of the product */
}
这比std::common_type
的限制性要小,但你不太可能在非算术类型上构建矩阵(但如果是?)
可以看到此技术在Coliru上运行。