2

我写了一个Matrix类。它在矩阵之间进行乘法运算。有时矩阵的乘法会产生一个 1x1 矩阵(例如,两个列向量的内积)。是否可以让一个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);

如果结果不是一一对应的,抛出异常也没关系。

4

3 回答 3

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 ); 
        }
        // ...
};

您的所有示例代码都可以按原样工作。

于 2013-01-23T22:12:33.737 回答
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;
};
于 2013-01-23T22:29:59.367 回答
0

除非尺寸成为类型的一部分。否则,您将必须始终进行标量转换,或者永远不会。您不能基于运行时事实来更改类型的编译时特性(无论它是否具有隐式转换) -无论两个维度的大小是否为 1。这需要编译器的预知。

于 2013-01-23T22:15:27.350 回答