Template-Auflösung mit Zeiger auf Memberfunktionen



  • Hi,

    zunächst der einfache Fall:

    Ich erzeuge für diverse freie Funktionen via Template Spezialisierungen:

    void f1() {};
    void f2() {};
    
    template<void(*pf)()>
    class Cl
    {
    public:
    	void go()
    	{
    		pf();  // <- dazu kommen wir gleich
    	}
    };
    
    Cl<f1> o;
    o.go();
    

    Nun möchte ich aber f1/f2 als Memberfunktionen einer Klasse implementieren:

    class Dida
    {
    public:
       void f1();
       void f2();
    };
    

    Natürlich ändern wir jetzt noch go, damit jeder zufrieden ist:

    void Cl:go(Dida& dida)
    {
    ...
    }
    

    Also ist nun das Objekt da, etc. Meine Quizfragen:

    1. wie sieht der Templateparameter aus?
    2. wie der Aufruf innerhalb von go()
    3. wie die Instanziierung des Templates?

    Grundsätzlich sollte die Vorgehensweise bei Memberfunktionen analog zu freien/statischen Funktionen doch möglich sein, aber ich bekomme das nicht richtig compiliert.

    Danke



  • Meinst Du so?

    template<class K, void (K::*pmf)()>
    class Cl
    {
    public:
        void go(K & blah)
        {
            (blah.*pmf)();
        }
    };
    
    ...
    Dida d;
    Cl<Dida,&Dida::f1> o;
    o.go(d);
    

    (ungetestet)

    Gruß,
    SP



  • Das hätte ich noch erwähnen sollen, ich würde das gerne nur mit einem Template-Parameter machen.

    Deine Lösung funktioniert.

    Ich hatte mir überlegt, ob genug Informationen vorliegen nur mit <void (K::*pmf)()>. Ich wollte gerne in der Instanziierung die Redundanz der Erwähnung der Klasse Dida in <Dida, &Dida::f> vermeiden.



  • #define CL(klasse,memfun) Cl<klasse,&klasse::memfun>
    
    ...
    Dida d;
    CL(Dida,f1) o;
    o.go(d);
    

    😉

    Sonst sehe ich keine Möglichkeit. In C++0x könnte man noch so etwas machen:

    template<class K, void (K::*Pmf)()>
    inline Cl<K,Pmf> make_cl_obj(void (K::*Pmf)())
    {
      return {};
    }
    
    ...
    Dida d;
    auto o = make_cl_obj(&Dida::f1);
    o.go(d);
    

    Gruß,
    SP



  • Wenn ich das Problem noch weiter einschränke und einen Freiheitsgrad reduziere:

    Das Objekt ist immer(!) vom Typ "Dida". D.h. über den Funktionszeiger kommen nur Memberfunktionen Dida::memfun rein. Ich muß kein Klassenswitching betreiben.



  • Ja und? Bist Du jetzt nicht in der Lage, den Template-Parameter "class K" rauszuschmeißen?



  • Argl. Jetzt sehe ich meinen Fehler, ich hatte (sinngemäß) in go noch den Templateparameter stehen statt dem Klassennamen.

    Danke für den Hinweis. 🙂


Anmelden zum Antworten