Template Memberfunktion spezialisieren



  • Hallo Leute,

    ich stehe gerade auf dem Schlauch 😕 .
    Bin gerade dabei eine allgemeine Optimierungsklasse zu schreiben.

    template <typename RT, typename AT>
    class CSolverGradient : public virtual CSolverBasis<RT, AT>
    {
    private:
    
    	//Gradient numerisch
    	AT berechne_gradienten(const AT & apunkt);
    
    	//neuen Punkt bestimmen
    	AT berechne_neuen_optimalpunkt(const AT & apunkt, const AT & agrad);
    
    public:
    
    	//Konstruktoren
    	CSolverGradient(){};
    
    	CSolverGradient(const CSFBasis<RT, AT> * afunktor):CSolverBasis(afunktor) {};
    
    	//Destruktor
    	virtual ~CSolverGradient(){};
    
    	//Solver starten
    	virtual void loese(const AT & astartwert);
    };
    

    Wenn ich jetzt die Funktionen berechne_gradienten und berechne_neuen_optimalpunkt für einen Rückgabewert (RT) double und einen Argumenttyp (AT) vector<double> spezialisieren will, muss ich dann das komplette Template spezialisieren?

    Könnt ihr mir auf die schnelle weiterhelfen?

    Danke.



  • KeineAhnung78 schrieb:

    Wenn ich jetzt die Funktionen berechne_gradienten und berechne_neuen_optimalpunkt für einen Rückgabewert (RT) double und einen Argumenttyp (AT) vector<double> spezialisieren will, muss ich dann das komplette Template spezialisieren?

    Erstmal: die beiden angesprochenen Funktionen haben AT als Rückgabewert. D.h. Argument- und Rückgabetyp der Spezialisierungen müssen gleich sein. Wenn du wirklich double und std::vector haben willst, musst du den Rückgabewert auf RT ändern.
    Dann geht's so:

    template <class R, class A>
    R CSolverGradient<R, A>::berechne_gradienten(const A& ) {
       // generische Impl
    }
    
    template <>
    double CSolverGradient<double,std::vector<double> >::berechne_gradienten(const std::vector<double>& ) {
     // Spezialisierung
     return 1.0;
    }
    


  • Danke,

    allerdings sollte der Rueckgabetyp bei den beiden Funktionen auch im allgemeinen Fall AT sein. Der Typ RT spielt in diesen beiden Funktionen gar keine Rolle.

    Wenn ich zwei Funktionen schreibe

    AT berechne_gradienten(const AT & apunkt);
    double berechne_gradienten(const std::vector<double> & apunkt);
    

    bekomme ich die Fehlermeldung, dass sie sich nur bezüglich des Rückgabewertes unterscheiden.

    Ich habe es jetzt so gelöst, dass ich nur die spezielle Funktion implementiere. Allerdings hätte ich die allgemeine schon sehr gerne um eine Exception auszuwerfen, wenn versucht wird, andere Datentypen zu verwenden.



  • KeineAhnung78 schrieb:

    Wenn ich zwei Funktionen schreibe

    AT berechne_gradienten(const AT & apunkt);
    double berechne_gradienten(const std::vector<double> & apunkt);
    

    bekomme ich die Fehlermeldung, dass sie sich nur bezüglich des Rückgabewertes unterscheiden.

    Welchen Compiler verwendest du? Die Variante ist nämlich durchaus legal.



  • Sorry, die Fehlermeldung lautet etwas anders (bezieht sich auf die Zeile der spezialisierten Funktion):

    member function already defined or declared.

    Compiler VC8

    😕



  • Innerhalb einer Template-Klasse kannst du keine Funktion überladen, die die selben Parameter hat, wie die übergebenen Template-Parameter, denn woher soll der Compiler dann wissen, welche Funktion er ausführen soll.

    HumeSikkins hat ja geschrieben, daß du Template-Methoden verwenden sollst.



  • HumeSikkins hat ja geschrieben, daß du Template-Methoden verwenden sollst.

    Alles palletti. Hab ja zusätzlich die spezialisierten Funktionen noch deklariert. Das geht nicht. Hab´s verstanden. Danke.


Anmelden zum Antworten