Operator-Definition



  • Nein, ich meine fürs FNI.



  • template<class T>
    T operator+(const T& Lhs, const T& Rhs);
    
    template<class T>
    class Foo{
        friend T operator+ <>(const T& Lhs, const T& Rhs);
    };
    
    template<class T>
    T operator+(const T& Lhs, const T& Rhs) {
    	// impl
    }
    

    Klappt das?



  • Was für einen Sinn soll es denn haben, wenn der Operator für T Freund-Zugriff auf deine Foo<>-Klasse hat, von der der übergebene Typ vermutlich gar nichts weiß?



  • CStoll schrieb:

    Was für einen Sinn soll es denn haben, wenn der Operator für T Freund-Zugriff auf deine Foo<>-Klasse hat, von der der übergebene Typ vermutlich gar nichts weiß?

    Der Template-Parameter T wird später mit dem Typ der Derived-Klasse gefüllt. Aber darum geht's ja zentral beim FNI, nicht?



  • Auch wenn ich mich damit als Nichtwisser oute: Wofür steht denn das "FNI"? Und kannst du ein wenig mehr über diese Klassenstruktur zeigen?
    (Wenn es wirklich um Vererbungs-Beziehungen geht, hilft eventuell auch ein richtig platziertes protected )



  • Erklär uns lieber, was du unter FNI verstehst.



  • FNI (Friend Name Injection) ist ein Teil des ADLs (Argument Dependet Lookup). FNI besagt, dass verwandte Klassen (nur nach oben) nach befreundeten Operatoren (Sichtbarkeit ist völlig egal) durchsucht werden:

    template<class T>
    class Notequal
    {
      friend bool operator!= (const T& Lhs, const T& Rhs)
      {
        return !(Lhs == Rhs);
      }
    };
    class MyInt : Notequal<MyInt>
    {
      public:
        int Value;
        bool operator== (const MyInt& Rhs) const
        {
          return this->Value == Rhs.Value;
        }
    };
    int main()
    {
      MyInt Foo, Bar;
      Foo == Bar; //Geht, logisch
      Foo != Bar; //Geht dank FNI
    }
    


  • Und was hindert dich daran, deinen Operator direkt in der Klassendefinition zu definieren (wie in deinem Beispielcode)? Mit Templates erübrigt es sich sowieso, den Code in einer eigenen Quelldatei zu verstecken (und wenn ich das richtig sehe, bleibt dem friend-Operator auch nicht viel übrig als andere Methoden von T zu nutzen).


  • Mod

    EOutOfResources schrieb:

    Hallo

    Es hört sich peinlich an aber ich habe keine Ahnung, wie ich diesen Operator ausserhalb der Klasse (also in der Source-Datei) definieren kann:

    template<class T>
    class Foo
    {
      friend T operator+ (const T& Lhs, const T& Rhs);
    };
    

    MfG, EOutOfResources

    Das ist unmöglich allgemein durchführbar, da du für jedes einzelne Templateargument eine eigene Funktionsdefinition schreiben müsstest.



  • CStoll schrieb:

    Und was hindert dich daran, deinen Operator direkt in der Klassendefinition zu definieren (wie in deinem Beispielcode)?

    So hatte ich es ursprünglich auch aber ich wollte wissen, ob und wie man den friend -Operator in die Source-Datei packen kann.

    camper schrieb:

    Das ist unmöglich allgemein durchführbar, da du für jedes einzelne Templateargument eine eigene Funktionsdefinition schreiben müsstest.

    Achso. Danke 👍 .


Anmelden zum Antworten