我写过Matrix
课程。它在矩阵之间进行乘法运算。有时,矩阵的乘法产生1×1矩阵(例如,两个列向量的内积)。是否有可能使Matrix
对象在逐个时直接返回标量值?
template <class T> class Matrix
{
public:
// ...
T& operator()(uint64_t unRow, uint64_t unCol = 0) throw(MatrixOutOfRange);
const T& operator()(uint64_t unRow, uint64_t unCol = 0) const throw(MatrixOutOfRange);
// ...
protected:
std::vector<T> MatrixArray;
// ...
};
// ...
template <class T>
T & Matrix<T>::operator()(uint64_t unRow, uint64_t unCol /*= 0*/) throw(MatrixOutOfRange)
{
/* Bound checking here */
return MatrixArray[m_unColSize * unRow + unCol];
}
template <class T>
const T & Matrix<T>::operator()(uint64_t unRow, uint64_t unCol /*= 0*/) const throw(MatrixOutOfRange)
{
/* Bound checking here */
return MatrixArray[m_unColSize * unRow + unCol];
}
// ...
示例代码:
Matrix<double> A (3, 1, 1.0, 2.0, 3.0);
Matrix<double> AT(1, 3, 1.0, 2.0, 3.0); // Transpose of the A matrix
Matrix<double> B (3, 1, 4.0, 5.0, 6.0);
Matrix<double> C();
C = AT * B;
double Result1 = C(0, 0);
double Result2 = (AT * B)(0, 0);
double Result3 = A.InnerProductWith(B)(0, 0);
当结果是一个一个矩阵时,我想删除不必要的元素位置说明符参数(0, 0)
。像这样:
C = AT * B;
double Result1 = C;
double Result2 = AT * B;
double Result3 = A.InnerProductWith(B);
如果结果不是一个一个,则抛出异常是可以的。
答案 0 :(得分:2)
是
这与std::vector::at()
类似,它也是一个编译时调用,除非满足某些运行时条件,否则它将始终抛出。
键入T
的转换运算符如下所示:
template <class T> class Matrix
{
public:
// ...
operator T &() {
// Throw here if size is not 1x1...
return (*this)( 0, 0 );
}
operator T const &() const {
// Throw here if size is not 1x1...
return (*this)( 0, 0 );
}
// ...
};
所有示例代码都可以正常工作。
答案 1 :(得分:0)
除非尺寸成为该类型的一部分。否则,您将不得不总是进行标量转换,或者永远不会。您无法根据运行时事实更改类型的编译时功能(无论是否具有隐式转换) - 无论两个维度中的大小是1还是不。这需要编译器的预知。
答案 2 :(得分:0)
我认为更好的方法是将尺寸作为类型的一部分:
template <class T, size_t NRows, size_t NCols>
class Matrix
{
public:
// ...
protected:
// ...
T M_storage[NRows][NCols]; // Or something...
};
然后使用模板专精将转换运算符添加到1x1矩阵:
template <class T>
class Matrix<T, 1, 1>
{
public:
// ...
operator T ()
{
return M_storage;//[0][0];
}
protected:
// ...
//T M_storage[1][1]; // Or something...
// Or even
T M_storage;
};