2

Matrixクラスを書きました。行列間の乗算を行います。行列の乗算によって 1x1 の行列が得られる場合があります (例: 2 つの列ベクトルの内積)。Matrixオブジェクトが1つずつあるときに、スカラー値を直接返すようにすることは可能ですか?

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)結果が 1 行 1 列の行列の場合、不要な要素位置指定子の引数を削除したいと考えています。このような:

C = AT * B;
double Result1 = C;
double Result2 = AT * B;
double Result3 = A.InnerProductWith(B);

結果が逐一でなければ例外を投げればOKです。

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

サイズが型の一部にならない限り、そうではありません。それ以外の場合は、常にスカラー変換を行うか、まったく行わないかのいずれかにする必要があります。サイズが両方の次元で 1 であるかどうかにかかわらず、実行時の事実に基づいて型のコンパイル時の機能 (暗黙的な変換があるかどうかにかかわらず) を変更することはできません。これには、コンパイラ側の事前認識が必要です。

于 2013-01-23T22:15:27.350 に答える
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 に答える