2016-10-24 5 views
5

Ich entdecke C++ und ich möchte eine Mini-mathematische Matrix librairy mit Vorlagen erstellen.C++ Operator Überladung Vorlage mit verschiedenen Argumenten

Hier möchte ich den Operator * überladen.

Wenn ich eine Matrix wie folgt beschreiben: M(y, x) mit M die Matrix Namen, y und x die Höhe und die Breite, eine Matrixmultiplikation so aussehen sollte:

M(a, b) * N(b, c) = R(a, c) 

Zur Zeit habe ich diesen Code:

template<unsigned int y, unsigned int x> 
class Matrix 
{ 
public: 
    Matrix() { } 
    ~Matrix() { } 

    Matrix<y, x2>& operator*(const Matrix<y2, x2>& right) 
    { 
     // code... 
    } 
private: 
    std::array<std::array<double, x>, y> m_values; 
}; 

So würde Ich mag Lage sein, zwei differents wie die Matrix zu multiplizieren:

Matrix<3, 4> m; 
Matrix<4, 2> n; 

// fill the matrix with values 

Matrix<3, 2> o = m * n; 

Ich habe gesucht, aber ich habe die Antwort auf diese Frage nicht gefunden (vielleicht weil ich nicht wirklich weiß, was ich genau suchen muss).

Vielen Dank für Ihre Hilfe :)

Antwort

3

Sie benötigen operator* eine Template-Memberfunktion, so etwas wie dies zu machen:

template <unsigned int y2, unsigned int x2> 
Matrix<y, x2> operator*(const Matrix<y2, x2>& right) 
{ 
    // code... 
} 

Beachten Sie, dass der Rückgabetyp ist nicht mehr eine Referenz, wie operator* sollte einen neuen Wert zurückgeben - wenn Sie möchten, können Sie eine komplementäre operator*= definieren, die die LHS-Matrix in-Place ändert.

Eine andere Sache zu beachten ist, dass Matrixmultiplikation nur sinnvoll ist, wenn die Dimensionen der Matrizen übereinstimmen: das heißt, wenn die Anzahl der Spalten in der LHS mit der Anzahl der Zeilen in der RHS übereinstimmt. Um dies zu erzwingen, können Sie ein static_assert in Ihrer Memberfunktion verwenden, um sicherzustellen, dass der Template-Parameter stimmen:

template <unsigned int y2, unsigned int x2> 
Matrix<y, x2> operator*(const Matrix<y2, x2>& right) 
{ 
    static_assert(y2 == x, "Matrix dimensions mismatched"); 
    // code... 
} 
0

Das ist ziemlich einfach, definieren operator* als Funktion Vorlage. Beispiel freie Funktionsvorlage:

template<unsigned y1, unsigned x1, unsigned y2, unsigned x2> 
Matrix<y1, x2> operator*(Matrix<y1, x1> const& l, Matrix<y2, x2> const& r) 
{ 
    // static_assert(x1 == y2, "Matrices cannot be multiplied"); 
    Matrix<y1, x2> ret{}; 
    // multiply 
    return ret; 
} 

Bitte beachten Sie, dass operator* kehrt nach Wert. Dies ist besonders wichtig, da Sie einen anderen Typ zurückgeben und kein Objekt haben, das einen Verweis auf (idiomatische Korrektheit) zurückgibt.

Verwandte Themen