C++ - template-friend-operator überladen
Was ist falsch an meinem code?
template<int E, int F>
class Float
{
friend Float<E, F> operator+ (const Float<E, F> &lhs, const Float<E, F> &rhs);
};
G++ nur hält Warnung:
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
Versuchte ich add <> after the function name here
wie bereits in der Warnung, aber g++ gibt mir eine Fehlermeldung.
Ich kompiliert den code mit clang++, es war in Ordnung, keine Warnung an alle.
- Sie können Lesen wollen parashift.com/c++-faq-lite/templates.html#faq-35.16
Du musst angemeldet sein, um einen Kommentar abzugeben.
Es ist nur eine Warnung über eine heikle Aspekt der Sprache. Wenn Sie deklarieren eine
friend
- Funktion, ist es nicht ein Mitglied der Klasse der Erklärung ist in. Sie können festlegen, es gibt für die Bequemlichkeit, aber es gehört eigentlich auf den namespace.Deklaration einer friend-Funktion, die nicht einer Vorlage innerhalb einer Vorlage-Klasse, noch deklariert eine nicht-template-Funktion im Namensraum. Es ist weder ein Mitglied der Klasse, noch selbst eine Vorlage. Es ist jedoch generiert von der Vorlage-Klasse.
Erzeugung von nicht-template-Funktionen-template ist ein bisschen verschwommen. Zum Beispiel, können Sie nicht fügen Sie eine Deklaration für die Funktion außerhalb des
class
block. Daher müssen Sie definieren, die es innerhalb derclass
block als auch, was Sinn macht, da die class-template wird generiert.Andere knifflige Sache über Freunde ist, dass die Erklärung innerhalb
class Float {}
nicht erklären die Funktion im Namensraum. Sie können nur finden über argument-abhängigen Bedeutung überlast Auflösung, d.h. die Angabe, dass ein argument hat TypFloat
(oder eine Referenz oder ein Zeiger). Dies ist nicht ein Problem füroperator+
, wie ist es wahrscheinlich zu überladen sowieso, und es wird nie aufgerufen, außer für die mit user-defined types.Ein Beispiel für ein mögliches Problem, stellen Sie sich vor, Sie haben eine conversion-Konstruktor
Float::Float( Bignum const& )
. AberBignum
nichtoperator+
. (Sorry, erfundenes Beispiel.) Sie wollen bis verlassen sich aufoperator+(Float const&, Float const&)
fürBignum
hinaus. Jetztmy_bignum + 3
wird nicht kompilieren, da weder operand ist einFloat
so kann er Sie nicht findenfriend
Funktion.Wahrscheinlich, Sie haben nichts zu befürchten, solange die Funktion in Frage ist ein
operator
.Oder, Sie können ändern Sie die
friend
eine Vorlage als gut. In diesem Fall muss er definiert werden außerhalb dieclass {}
block, und erklärte, bevor er, statt sein müssen deklariert und definiert innen.Dies ist ein ziemlich altes Thema, aber ich denke, die einfachste Möglichkeit zum deklarieren der Betreiber ist es zu definieren, innen Float-Klasse.
Die syntax ist einfacher zu schreiben und zu verstehen, und es wird funktionieren genau das gleiche (außer, dass es inline), wird es nicht sein, eine member-Funktion.
operator +
, in der Regel die einfachste und beste Weg ist die Umsetzungoperator +=
als Mitglied, und dann implementierenoperator +
als nicht-Mitglied nicht-Freund in Bezug auf+=
. Dies stellt sicher, Sie haben beide Operatoren definiert und Verhalten Sie sich konsequent.Müssen Sie genau das tun, als die Warnungen sagen:
Dies erklärt eine vollständige Spezialisierung des Betreibers Vorlage ein Freund von einer bestimmten Instanz der Klasse Vorlage. In einem Kommentar zu der Frage UncleBens hat freundlicherweise ein link zu einer Erklärung, warum das so kompliziert ist.