2011-04-06 47 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);