Überladen von C ++ - Vorlagen-Friend-Operatoren

8

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.

    
Zifei Tong 21.10.2010, 16:24
quelle

3 Antworten

24

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.

%Vor%     
Potatoswatter 21.10.2010, 16:37
quelle
3

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.

    
slepasteur 16.07.2013 17:50
quelle
1

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.

    
sbi 21.10.2010 16:37
quelle