Ich schreibe eine kleine Matrixbibliothek in C ++ für Matrixoperationen. Mein Compiler beschwert sich jedoch, wo es vorher nicht war. Dieser Code wurde 6 Monate lang in einem Regal belassen und dazwischen habe ich meinen Computer von Debian Etch auf Lenny (g ++ (Debian 4.3.2-1.1) 4.3.2) aktualisiert. Auf einem Ubuntu-System mit demselben g ++ habe ich jedoch das gleiche Problem .
Hier ist der relevante Teil meiner Matrixklasse:
namespace Math
{
class Matrix
{
public:
[...]
friend std::ostream& operator<< (std::ostream& stream, const Matrix& matrix);
}
}
Und die "Implementierung":
using namespace Math;
std::ostream& Matrix::operator <<(std::ostream& stream, const Matrix& matrix) {
[...]
}
Dies ist der vom Compiler angegebene Fehler:
matrix.cpp: 459: Fehler: 'std :: ostream & Math :: Matrix :: operator << (std :: ostream &, const Math :: Matrix &)' muss genau ein Argument annehmen
Ich bin ein bisschen verwirrt von diesem Fehler, aber andererseits ist mein C ++ etwas rostig geworden, nachdem ich in diesen 6 Monaten viel Java gemacht habe. :-)
quelle
operator<<
im Namespace von seinMath
? Es scheint, dass es im globalen Namespace sein sollte. Ich bin damit einverstanden, dass mein Compiler möchte, dass es im Namespace von istMath
, aber das macht für mich keinen Sinn.Ich erzähle Ihnen nur von einer anderen Möglichkeit: Ich verwende dafür gerne Freundedefinitionen:
Die Funktion wird automatisch auf den umgebenden Namespace ausgerichtet
Math
(obwohl ihre Definition im Bereich dieser Klasse angezeigt wird), ist jedoch nur sichtbar, wenn Sie den Operator << mit einem Matrix-Objekt aufrufen, wodurch die argumentabhängige Suche diese Operatordefinition findet. Dies kann manchmal bei mehrdeutigen Aufrufen hilfreich sein, da es für andere Argumenttypen als Matrix nicht sichtbar ist. Wenn Sie die Definition schreiben, können Sie auch direkt auf in Matrix definierte Namen und auf Matrix selbst verweisen, ohne den Namen mit einem möglicherweise langen Präfix zu qualifizieren und Vorlagenparameter wie bereitzustellenMath::Matrix<TypeA, N>
.quelle
Um Mehrdad Antwort hinzuzufügen,
In Ihrer Implementierung
quelle
Angenommen, es handelt sich um eine Überladung
operator <<
für alle Klassen, von denen abgeleitet wurdestd::ostream
, um dieMatrix
Klasse zu behandeln (und nicht um eine Überladung<<
für eineMatrix
Klasse), ist es sinnvoller, die Überladungsfunktion außerhalb des Math-Namespace im Header zu deklarieren.Verwenden Sie eine Friend-Funktion nur, wenn die Funktionalität nicht über die öffentlichen Schnittstellen erreicht werden kann.
Matrix.h
Beachten Sie, dass die Operatorüberladung außerhalb des Namespace deklariert wird.
Matrix.cpp
Wenn andererseits Ihre Überlastungsfunktion hergestellt werden muss, benötigt ein Freund Zugriff auf private und geschützte Mitglieder.
Math.h
Sie müssen die Funktionsdefinition nicht nur mit einem Namespace-Block versehen
using namespace Math;
.Matrix.cpp
quelle
In C ++ 14 können Sie die folgende Vorlage verwenden, um jedes Objekt zu drucken, das eine T :: print (std :: ostream &) const; Mitglied.
In C ++ 20 können Konzepte verwendet werden.
quelle
std::ostream&
, da es sowieso der Rückgabetyp ist?