2016-04-03 7 views
4

Ich versuche, eine Matrixklasse zu implementieren, die sowohl echte als auch komplexe Matrizen verarbeiten kann. Ich habe Probleme, wenn ich versuche, den Multiplikationsoperator zu überladen. Genauer gesagt, wenn ich versuche, eine doppelte Matrix mit einer komplexen Matrix zu multiplizieren (in dieser Reihenfolge). Das Ergebnis sollte komplex sein, aber der Operator * ist ein Mitglied einer Doppelmatrix. In diesem Fall sehe ich nicht, wie man eine komplexe Matrix zurückgibt (ich habe versucht, einen Freundoperator zu verwenden, das scheint auch nicht zu funktionieren). Hier ist der relevante Code-Schnipsel:C++ Operatorüberladung für eine Matrixklasse mit reellen und komplexen Matrizen

template <class V> Matrix<T> operator *(const Matrix<V> &b) 
{ 
    long i, j, k; T temp; Matrix<T> c(mRows, b.Cols()); 

    for (i = 0; i < mRows; i++) 
     for (j = 0; j < c.Cols(); j++) 
     { 
      for (temp = 0, k = 0; k < mCols; k++) 
       temp += this->Element(i, k)*b.Element(k, j); 

      c(i, j) = temp; 
     } 

     return c; 
} 

Also, wenn A real ist, und B und C sind komplex, C = B A funktioniert gut, aber C = A B nicht. Insbesondere weist der Compilerfehler die Zeile "temp + =" darauf hin, dass kein globaler Operator gefunden wurde, der den Typ komplex (oder keine akzeptable Konvertierung) akzeptiert. Ich möchte vermeiden, die Vorlage für reale und komplexe Typen vollständig zu spezialisieren, gibt es einen Weg um dies zu umgehen?

Vielen Dank im Voraus.

+0

Sie wollen 'template Matrix operator * (const Matrix & a, const Matrix & b)' –

+0

Siehe auch [Operator Overloading] (http://stackoverflow.com/questions/4421706/operator-overloading) zu erklären, Bitte. –

+0

Danke, aber das müsste als Freund-Operator deklariert werden, oder? Und dies erzeugt ein neues Problem, nämlich dass mehr als ein Operator den Operanden entspricht. – DJM123

Antwort

-1

ich denke Problem darin: this-> Element (...)

ich weiß nicht genau, was für Fest tun. aber ich befehle, beide Matrix zu ändern. (A < -> B)

+1

Sorry, ich habe nicht bekommen, was du geschrieben hast. Könntest du es mehr ausarbeiten? – surajsn

+0

Sie sagen: C = BA funktioniert gut, aber C = AB funktioniert nicht. Ich erzähle: löse dieses Problem in zwei Richtungen. 1. Professional 2. Engineering Weg 2. ist einfach. Auf diese Weise sagen Sie uns, dass Sie die Antwort möglichst einfach erhalten. Sie erhalten die Antwort mit der Änderungsmatrix A und B zusammen. auf der anderen Seite wandelst du C = AB in C = BA um. auf der Suche nach einfachen Weg für die Antwort nicht verpackt Weise –

+0

Bro. !!! Ich bitte Sie, meine Worte ** ernsthaft **, aber nicht persönlich zu beachten. Ich habe dein Profil gesehen, du bist sehr enthusiastisch Antwort hier zu schreiben, das ist so nett von dir. aber ich konnte leicht sehen, dass die meisten deiner Antworten ** abgelehnt wurden. Ich habe deine Antworten gesehen und herausgefunden, dass du sie nicht gut erklärst. Deshalb bitte ich Sie, etwas zu recherchieren, bevor Sie die Antwort schreiben, und versuchen Sie es immer wieder, versuchen Sie immer, beim Schreiben der Antwort Ihr Bestes zu geben, denn es geht nicht um Reputation oder Abzeichen. Es geht darum, dein Bestes zu geben, also nimm es nicht als selbstverständlich hin. ** Weiter lächeln und Happy Coding **. :) – surajsn

2

Wie in den Kommentaren erwähnt, in diesem Fall ist es besser, eine Dritt Überlastung der operator* zu verwenden (die mit der Matrix-Klasse be- friend ED).

Aber das ist nicht der Grund, warum es nicht funktioniert. Das Problem hier ist die Erklärung von

T temp; Matrix<T> c; 

in Ihrem in-class operator*. Sie sollten jede T mit std::common_type_t<T,U> ersetzen:

using C = std::common_type_t<T,U>; 
C temp; Matrix<C> c; 

Ansonsten ist das Element-Typ der zurückgegebenen Matrix wird die gleiche wie die der anrufenden Matrix immer sein. Das heißt, wenn Sie C = A*B aufrufen, die als C = A.operator*(B) aufgelöst wird, ist der Elementtyp C derselbe wie A.

Dann, wenn A ein Matrix<double> ist und Sie multiplizieren es mit einem Matrix<complex<double> >, würden Sie einen Matrix<double> als Rückkehr bekommen - was offensichtlich falsch ist.

+0

Fantastisch, liebe diese Lösung, danke! Es arbeitet tatsächlich mit der ursprünglichen binären Formulierung von Überladung *; Gibt es einen Grund, diesen Ansatz zu meiden, d.h. sind Überladungen von Freunden vorzuziehen? – DJM123

+0

@ DJM123: Gern geschehen. Zur Frage, siehe [hier] (http://stackoverflow.com/a/4421729/2412846). – davidhigh

+0

@ DJM123: ... aber mein Link gibt keine Motivation für die Verwendung der Nichtmitgliedsüberlastung, daher besser [hier] (http://stackoverflow.com/a/4622467/2412846). – davidhigh

Verwandte Themen