funktionspointer im template typedef definieren



  • Hallo,

    also folgende Situation, ich habe eine Templateklasse. Als Template möchte ich
    eine Objektfunktion definieren die entsprechend aufgerufen wird.

    Das mache ich ungefähr so:

    template< typename FUNCTION >
    class TestKlasse
    {
    [...]
    
    void Do(FUNCTION func)
    {
    [..]
    OBJECT* y = GetObject();
    float x = y->func();
    }
    }
    

    Nun möchte ich ein typedef dieser Templateklasse setzen, der explizit eine Objektfunktion definiert. Und hier habe ich so meine Probleme, da ich nicht weiß wie ich das machen soll (obwohl ich noch nicht mal weiß ob der oben gezeigte Code so funktioniert. Falls nicht würde ich auch gerne wissen wie ich das richtig definieren kann).

    Es soll ungefähr so aussehen (was natürlich so nicht stimmt):

    typedef TestKlasse<OBJECT::GetValue()> ValueKlasse;
    

    Meine Frage ist also, wie kann ich solch eine Funktion eines Objektes im typedef definieren?

    Vielen Dank schonmal
    Gruß


  • Mod

    Das geht nicht. Templateparameter können nur Datentypen oder integrale Werte sein. Ein Funktionszeiger ist keines davon.

    edit: Ach ja, ein Pointer ist natürlich auch integral. Vergiss was hier stand.



  • Nun ja, das sollte ja schon gehen à la:

    template<void (*func)(int)>
      struct foo {
         void machWas() { func(42); }
      };
    
      void eins(int i) { std::cout << i << std::endl; }
      void zwei(int i) { std::cout << (i*i) << std::endl; }
    
      int main() {
        foo<eins> a;
        foo<zwei> b;
        a.machWas();
        b.machWas();
      }
    

    und da dachte ich dass es doch auch durchaus möglich sein sollte eine templateklasse mit einem undefinerten funktionspointer zu definieren und entsprechend eine typedef zu formulieren. Woran liegt es denn dass es undefiniert nicht geht? Das wäre ärgerlich. Gibt es denn einen Workaround?

    Es ist im übrigen eine Partikelklasse, die ich aber nicht hier aufführen möchte.

    Danke



  • template<void (*func)(int) >
    struct sF
    {
        static void machWas(int j) { (*func)(j); }
    };
    
    void eins(int i) { cout << i << endl; }
    void zwei(int i) { cout << i * 2 << endl; }
    
    typedef sF< &eins > tEins;
    typedef sF< &zwei > tZwei;
    
    template < typename type, typename arg >
    void foo (type &Type, arg Arg)
    {
        Type.machWas(Arg);
    }
    
    int main(int argc, char *argv[])
    {
        tEins Eins;
        tZwei Zwei;
    
        foo(Eins, 10);
        foo(Zwei, 10);
    
        return EXIT_SUCCESS;
    }
    

    Hoffe das Du es gebrauchen kannst

    Lichtlein



  • Wenn die Funktionen nur von einer Klasse sind, gehts so:

    #include <iostream>
    using namespace std;
    
    struct Bar
    {
    	void eins(int i) { std::cout << i << std::endl; }
    	void zwei(int i) { std::cout << (i*i) << std::endl; }
    };
    
    template<void (Bar::*func)(int)>
    struct foo
    {
    	void machWas() { Bar bar; (bar.*func)(42); }
    };
    
    int main()
    {
    	foo<&Bar::eins> a;
    	foo<&Bar::zwei> b;
    	a.machWas();
    	b.machWas();
    }
    


  • Danke euch! Lichtlein, das sieht gut aus, das werde ich so machen.

    thx!



  • Jetzt mal ein Vorschlag mit Member Funktionen.

    Sieht aber bald so aus als ob man für Dein Problem die std/binder nehmen könnte?

    template<typename object, typename arg, void (object::*func)(arg) >
    struct sF
    {
        typedef object  tObject;
        typedef arg     tArg;
        static void machWas(object &Object, arg j) { (Object.*func)(j); }
    };
    
    struct cObject
    {
        void einsInt(int i) { cout << i << endl; }
        void zweiInt(int i) { cout << i * 2 << endl; }
    
        void einsLong(long l) { cout << l * 10 << endl; }
        void zweiLong(long l) { cout << l * 20 << endl; }
    };
    
    typedef sF< cObject, int, &cObject::einsInt > tEinsInt;
    typedef sF< cObject, int, &cObject::zweiInt > tZweiInt;
    
    typedef sF< cObject, long, &cObject::einsLong > tEinsLong;
    typedef sF< cObject, long, &cObject::zweiLong > tZweiLong;
    
    template < typename type >
    void foo(typename type::tObject &Object, typename type::tArg Arg)
    {
        type::machWas(Object, Arg);
    }
    
    int main(int argc, char *argv[])
    {
        cObject Object;
    
        foo<tEinsInt>(Object, 10);
        foo<tZweiInt>(Object, 10);
        foo<tEinsLong>(Object, 10);
        foo<tZweiLong>(Object, 10);
    
        return EXIT_SUCCESS;
    }
    

    Lichtlein



  • Katachi schrieb:

    ich habe eine Templateklasse. Als Template möchte ich
    eine Objektfunktion definieren

    Du hast ein Klassen-Template und möchtest über einen Template-Parameter steuern, welche Elementfunktion eines Objekts aufgerufen werden soll.

    Ja, das geht. Es gibt Nicht-Typ-Template-Parameter. Dazu gehören auch Zeiger/Referenzen auf "Dinge" (Objekte und Funktionen) mit externer Bindung, einschließlich Zeiger auf Elementfunktionen.


Anmelden zum Antworten