Was ist falsch an meinem Code?
%Vor%G ++ warnt nur:
float.h:7: warning: friend declaration ‘Float<E, F> operator+(const Float<E, F>&, const Float<E, F>&)’ declares a non-template function
float.h:7: warning: (if this is not what you intended, make sure the function template has already been declared and add <> after the function name here) -Wno-non-template-friend disables this warning
Ich habe versucht, add <> after the function name here
wie im Warnhinweis erwähnt, aber g ++ gibt mir einen Fehler.
Ich habe den Code mit clang ++ kompiliert, es war in Ordnung, keine Warnung.
Es ist nur eine Warnung vor einem schwierigen Aspekt der Sprache. Wenn Sie eine friend
-Funktion deklarieren, ist sie kein Mitglied der Klasse, in der sich die Deklaration befindet. Sie kann sie hier zur Vereinfachung definieren, aber sie gehört tatsächlich zum Namespace.
Das Deklarieren einer Friend-Funktion, bei der es sich nicht um eine Vorlage handelt, innerhalb einer Klassenvorlage deklariert immer noch eine Nicht-Template-Funktion im Namespace. Es ist weder ein Mitglied der Klasse, noch selbst eine Vorlage. Es wird jedoch von der Klassenvorlage erzeugt .
Das Generieren von Nicht-Template-Funktionen aus einer Vorlage ist ein wenig verschwommen. Sie können beispielsweise keine Deklaration für diese Funktion außerhalb des Blocks class
hinzufügen. Daher müssen Sie es auch im Block class
definieren, was sinnvoll ist, weil die Klassenvorlage es erzeugt.
Eine weitere knifflige Sache bei Freunden ist, dass die Deklaration in class Float {}
die Funktion im Namespace nicht deklariert. Sie können es nur durch eine argumentabhängige Bedeutungsüberladungsauflösung finden, d. H. Durch Angabe eines Arguments vom Typ Float
(oder einer Referenz oder eines Zeigers). Dies ist kein Problem für operator+
, da es wahrscheinlich ohnehin überladen ist und nie aufgerufen wird, außer bei benutzerdefinierten Typen.
Stellen Sie sich ein Beispiel für ein potenzielles Problem vor, wenn Sie einen Konvertierungskonstruktor Float::Float( Bignum const& )
haben. Aber Bignum
hat nicht operator+
. (Entschuldigung, erfundenes Beispiel.) Sie möchten sich auf operator+(Float const&, Float const&)
für Bignum
addition verlassen. Nun wird my_bignum + 3
nicht kompiliert, da keiner der beiden Operanden Float
ist und daher die friend
Funktion nicht finden kann.
Wahrscheinlich müssen Sie sich keine Sorgen machen, solange die fragliche Funktion operator
ist.
Oder Sie können friend
auch als Vorlage ändern. In diesem Fall muss es außerhalb des Blocks class {}
definiert und davor deklariert werden, anstatt innerhalb von deklariert und definiert werden zu müssen.
Das ist ein ziemlich altes Thema, aber ich denke, der einfachste Weg, den Operator zu deklarieren, ist, ihn innerhalb der Float-Klasse zu definieren.
%Vor%Die Syntax ist einfacher zu schreiben und zu verstehen und wird genauso funktionieren (außer dass es inline ist), es wird keine Member-Funktion sein.
MSDN: in Klassendeklarationen definierte Friend-Funktionen werden nicht in dem Bereich der umschließenden Klasse berücksichtigt; Sie sind im Dateiumfang.
Sie müssen genau so vorgehen, wie die Warnungen sagen:
%Vor%Dies deklariert eine vollständige Spezialisierung des Operator-Templates als Freund einer bestimmten Instanz der Klassenvorlage. In einem Kommentar zu der Frage hat OnkelBens freundlicherweise einen Link zu einer Erklärung zur Verfügung gestellt Das ist so kompliziert.
Tags und Links c++ templates operator-overloading friend