friend OPerator bei Template-Klasse



  • Hi Fans der Königin unter allen Programmiersprachen 😃 ,

    mal angenommen, ich habe zwei Template-Klassen Vektor und Matrix, die ich auch miteinander Multiplizieren will:

    #ifndef Vector_H
    #define Vector_H
    
    #include "Matrix.h"
    using namespace std;
    
    template <class T> 
    class Vector {
    
      private:
        ...
    
      public:
        ...
        friend Vector<T> operator* (const Matrix<T>& m, const Vector<T>& v);
        ...       
    
        }; // end of class Vector<T>
    
    #endif
    

    und die Matrix-Klasse:

    #ifndef MATRIX_H
    #define MATRIX_H
    
    #include "Vector.h"
    using namespace std;
    
    template <class T> 
    class Matrix {
    
      private:
        ...
      public:
        ...
        friend Vector<T> operator* (const Matrix<T>& m, const Vector<T>& v);
        ...
        }; // end of class Matrix<T>
    
    template <class T> Vector<T> operator* (const Matrix<T>& m, const Vector<T>& v) {...
    
        }
    
    #endif
    

    bersetzen des Codes führt zu einer Warnung:

    In file included from ...,

    Vector.h:106: warning: friend declaration `Vector<T> operator*(const Matrix<T>&, const Vector<T>&)' declares a non-template function

    Frage: Wieso kommt diese Warnung und was kann ich dagegen tun?

    Grüße LIBS



  • Habs selber herausgefunden:

    es muss in den Deklarationen heißen:

    ... 
        friend Vector<T> operator*<T> (const Matrix<T>& m, const Vector<T>& v);
        ...
    

    Die eigentlich Funktionsdefinition bleibt unverändert:

    template <class T> Vector<T> operator* (const Matrix<T>& m, const Vector<T>& v) {...
    
        }
    

    und schon brummt's ...



  • Frage: Wieso kommt diese Warnung und was kann ich dagegen tun?

    Was du dagegen tun kannst, hast du ja selbst bereits rausgefunden.
    Das "wieso kommt die Warnung" wird im Standard festgelegt.

    Vereinfacht ausgedrückt steht dort, dass es für einen Funktions-Namen in einer friend-*Deklaration* auf den *keine* spitzen Klammern folgen zwei Möglichkeiten gibt:

    1. Falls es sich bei dem Namen um einen *unqualifizierten* Namen handelt, so bezeichnet dieser Name *niemals* eine Template-Instanz sondern immer eine normale Funktion. Ist am Punkt der friend-Deklaration bisher keine Funktion mit dem angegebenen Namen bekannt, so wird eine solche durch die friend-Deklaration deklariert.
    Eine solche Deklaration kann auch eine Definition sein.

    2. Handelt es sich um einen qualifizierten Namen (z.B. ::foo oder ns::bar), dann *muss zuvor* bereits eine Funktion mit diesem Namen deklariert worden sein (die friend-Deklaration ist also keine einführende Funktionsdeklaration). Es kann aber sowohl eine Template- als auch eine normale Funktion sein. Im Zweifelsfall wird eine normale Funktion aber bevorzugt.
    Eine solche Deklaration kann *niemals* eine Definition sein.

    In deinem Fall ist der Name um den es geht operator*. Dieser ist zweifelsohne ein *unqualifzierter* Name. Außerdem folgen *keine* spitzen Klammern. Damit fällt die friend-Deklaration also in Kategorie 1 und bezeichnet damit niemals eine Template-Funktion sondern eine normale Funktion -> Die Warnung.


Anmelden zum Antworten