2011-04-06 48 views
0

昨天我問了一個問題,當然得到了一些很好的答案。 現在我在我的項目結束,我再次卡住,無法找出答案。 我將把我的代碼中最相關的部分放在這裏,希望能夠從你們所有人那裏獲得一些見解。 要求是:我不能更改我的main.cpp中的代碼,並且我的頭文件應該儘可能簡單。爲什麼我使用operator *失敗?

有了這樣離開這裏的方法是代碼:這是我的Matrix.h文件

#ifndef MATRIX_H 
#define MATRIX_H 
#include <vector> 
#include <iostream> 
#include <math.h> 
#include <complex> 
using namespace std; 
namespace theMatrix { 

template <typename T, size_t ROWS, size_t COLS> 
class Matrix { 
    friend class Matrix; 
public: 
    Matrix(const T & init = T()) : elts(ROWS, vector<T>(COLS, init)) { 
    }; 
    const vector<T> & operator[](int ROWS) const { 
     return elts[ROWS]; 
    }; 

    vector<T> & operator[](int ROWS) { 
     return elts[ROWS]; 
    }; 
    //matrixMult 

    template<size_t INNER> 
    Matrix & matrixMult(const Matrix<T, ROWS, INNER> & mat1, const Matrix<T, INNER, COLS> & mat2) { 
     for (int i = 0; i < ROWS; i++) { 
      for (int j = 0; j < COLS; j++) { 
       //elts[i][j] = 0; 
       for (int k = 0; k < INNER; k++) { 
        this->elts[i][j] += mat1.elts[i][k] * mat2.elts[k][j]; 
       } 
      } 
     } 
     return *this; 
    }; 

    //print function 

    void print(ostream & out) const { 
     for (int i = 0; i < ROWS; i++) { 
      for (int j = 0; j < COLS; j++) { 
       out << elts[i][j]; 
      } 
      out << "\n"; 
     } 
    }; 

private: 
    vector< vector<T> > elts; 
}; 
//Operator<< 

template <typename T, size_t ROWS, size_t COLS> 
ostream & operator<<(ostream & out, const Matrix<T, ROWS, COLS> & elts) { 
    elts.print(out); 
    return out; 
}; 


//Operator* 

template <typename T, size_t ROWS, size_t COLS> 
Matrix<T, ROWS, COLS> operator*(const Matrix<T, ROWS, COLS> & lhs, const Matrix<T, ROWS, COLS> & rhs) { 
    Matrix<T, ROWS, COLS> returnVal; 
    return returnVal.matrixMult(lhs, rhs); 
}; 
//operator matrixMult 

template <typename T, size_t ROWS, size_t INNER, size_t COLS> 
inline void matrixMult(const Matrix<T, ROWS, INNER> & mat1, const Matrix<T, INNER, COLS> & mat2, Matrix<T, ROWS, COLS> & mat3) { 
    mat3 = matrixMult(mat1, mat2); 
}; 

這是我的main.cpp:

#include <iostream> 
#include <fstream> 
#include <string> 
#include <cstdlib> // for rand() 
#include "Matrix.h" 

using namespace std; 
using namespace theMatrix; 

template <typename T, size_t ROWS, size_t COLS> 
void randomize(Matrix<T, ROWS, COLS> & mat) 
// Put random values in a Matrix. 
// Note: It must be possible to assign T an int value. 
{ 
for (size_t i = 0; i < ROWS; i++) 
    for (size_t j = 0; j < COLS; j++) 
     mat[i][j] = (rand() % 21) - 10; // Random number in range -10,...,+10 
} 

struct Complex 
{ 
Complex(double re = 0.0, double im = 0.0) : real(re), imag(im) { } 
Complex & operator+=(const Complex & rhs) 
{ 
    real += rhs.real; 
    imag += rhs.imag; 
    return *this; 
} 
Complex & operator-=(const Complex & rhs) 
{ 
    real -= rhs.real; 
    imag -= rhs.imag; 
    return *this; 
} 
Complex & operator*=(const Complex & rhs) 
{ 
    real = real * rhs.real - imag * rhs.imag; 
    imag = real * rhs.imag + imag * rhs.real; 
    return *this; 
} 
double real; 
double imag; 
}; 
Complex operator+(const Complex & lhs, const Complex & rhs) 
{ 
return Complex(lhs.real + rhs.real, lhs.imag + rhs.imag); 
} 
Complex operator-(const Complex & lhs, const Complex & rhs) 
{ 
return Complex(lhs.real - rhs.real, lhs.imag - rhs.imag); 
} 
Complex operator*(const Complex & lhs, const Complex & rhs) 
{ 
return Complex(lhs.real * rhs.real - lhs.imag * rhs.imag, lhs.real * rhs.imag + lhs.imag * rhs.real); 
} 
ostream & operator<<(ostream & out, const Complex & c) 
{ 
out << "(" << c.real << " + " << c.imag << "i)"; 
return out; 
} 

int main() 
{ 
// Matrix multiplication tests: 
Matrix<int, 2, 3> m4; 
randomize(m4); 
Matrix<int, 3, 5> m5; 
randomize(m5); 
Matrix<int, 2, 5> m6; 
Matrix<int, 2, 5> m7; 
matrixMult(m4, m5, m7); 
out << "m6 == m4 * m5: " << (m6 == m4 * m5) << endl; // here is the first error 

// Matrices of Complex: 
Matrix<Complex, 2, 8> m11; 
randomize(m11); 
Complex c(1, -3); 
Matrix<Complex, 8, 3> m12; 
randomize(m12); 
out << "m11 * m12: " << endl << m11 * m12 << endl; // Here is the second error 
out.close(); 
} 

我有隻有兩個錯誤,這些錯誤與我一直試圖解決好幾個小時的複雜運算符*聲明相沖突,我無法弄清楚。 下面是錯誤的:

Error  1  error C2678: binary '*' : no operator found which takes a left-hand operand of type 'nkumath::Matrix<T,ROWS,COLS>' (or there is no acceptable conversion) 

Error  2  error C2678: binary '*' : no operator found which takes a left-hand operand of type 'nkumath::Matrix<T,ROWS,COLS>' (or there is no acceptable conversion)    

再次感謝大家對這種幫助。

編輯:這是解決方案!我投了票。謝謝!!!

//Operator* 
template <typename T, size_t ROWS, size_t INNER, size_t COLS> 
Matrix<T, ROWS, COLS> operator*(const Matrix<T, ROWS, INNER> & lhs, const Matrix<T, INNER, COLS> & rhs) { 
    Matrix<T, ROWS, COLS> returnVal; 
    return returnVal.matrixMult(lhs, rhs); 
}; 
+1

您錯過了兩個矩陣相乘的重載運算符。我沒有看到它張貼在這裏。它正在尋找模板,行,列。對於重載的*運算符函數,您只需具有Complex,Complex。 – 2011-04-06 18:56:14

+0

作業?聞起來像...... – 2011-04-06 18:57:35

+0

@ 0A0D:有一個重載('operator *(const Matrix &lhs,const Matrix &rhs)'),它只是無效在這種情況下。 – 2011-04-06 19:05:41

回答

4

你的模板operator *超載不允許兩個輸入矩陣,以大小不同。

+0

這聽起來不錯,模板化的'operator *'在兩個矩陣中都有相同的ROWS COLS。在你的主體中,你正在乘以不同類型的'Matrix '和'Matrix ',所以你的模板化操作符*不符合要求。您需要定義一些模板,如'template Matrix operator *(Matrix const&lhs,Matrix const&rhs)' – 2011-04-06 19:09:02

+0

我的朋友,感謝您澄清這一點。那正是我做錯的地方。這是固定的代碼。 – Truesky 2011-04-06 19:14:40

+0

// Operator * \t template \t Matrix operator *(常量矩陣&lhs,常量矩陣 returnVal; \t \t return returnVal.matrixMult(lhs,rhs); \t}; – Truesky 2011-04-06 19:15:07

2

你的問題是,模板operator*需要相乘的兩側是相同矩陣實例。 T,ROWSCOLS不能推導爲lhsrhs類型在同一函數中的不同值。

template <typename T, size_t ROWS, size_t COLS> Matrix<T, ROWS, COLS> operator*(const Matrix<T, ROWS, COLS> & lhs, const Matrix<T, ROWS, COLS> & rhs); 

Matrix<int, 2, 3> m4; 
Matrix<int, 3, 5> m5; 
m4*m5; 

如果編譯器推斷ROWSCOLS爲2和3對上述多元化,rhs類型將不匹配您的模板運算符*。如果編譯器將ROWS推斷爲3並將COLS推導爲5,則lhs類型將不匹配。

你需要定義如何不同大小的矩陣情況下的乘法應該工作,並作出e.g:

template <typename T, size_t ROWS_L, size_t COLS_L, size_t ROWS_R, size_t COLS_R> 
Matrix<T, ROWS_L, COLS_L> operator*(const Matrix<T, ROWS_L, COLS_L> & lhs, const Matrix<T, ROWS_R, COLS_R> & rhs);