vererbung, funktionsparameter und funktionszeiger.



  • class a { };
    class b : public a { };
    
    void f(a& A);
    
    template<typename T> class x {
      public:
        void f(void (*f)(T t));
    };
    
    int main(void) {
      x<b&> X;
      X.f(f);
      return 0;
    }
    

    wieso ist in dem fall ein b kein a, sodass der compiler die globale funktion f nicht auf die methode f der klasse übergeben will?



  • void f(a* A);
    

    Zeiger kann man Kasten, Instanzen nicht?



  • ich hab hier eine referenz und keine instanz. ein aufruf der globalen funktion f mit einer instanz von b klappt natürlich wunderbar. deshalb sollte eben auch der funktionszeiger so behandelt werden.



  • hola

    weil du deinen parameter void()(a&) nicht in einen parameter void()(b&) wandeln kannst.
    die beiden funktionszeiger als selbst sind naemlich nicht mit einander verwandt, sprich void()(b&) ist nicht von void()(a&) abgeleitet.

    Meep Meep



  • so wuerde es gehen. haengt naetuerlich davon ab, was du machen willst

    class a { };
    class b : public a { };
    
    void f(a& A) { }
    
    template<typename T> class x {
      public:
    	 typedef void (*myfunc)(a& temp);
    	 void f(myfunc) { myfunc(b); }
    	 T var;
    };
    
    int main(void) {
      x<b> X;
      X.f(f);
      return 0;
    }
    

    Meep Meep



  • @Meep Meep
    leider ist das keine option. die leute werden halt je eine funktion erstellen müssen anstatt einer mit der gemeinsamen basis klasse.

    ich experimentier mit gcc 4.3 und den neuen variadic templates, um damit eine generische event api zu bauen. beispielweise bei der gui programmierung wäre das dann praktisch, wenn ein event zb. einen button als parameter hat und ein anderer event ein anderes widget. erben alle widgets von einer gemeinsamen basisklasse, so könnte man generische event, wie drauf klicken oder so, über die generische basisklasse abfangen. aber leider klappt das nur mit mehreren funktionen (einer pro widget).

    grundsätzlich sehe ich keinen technischen grund, wieso mein code nicht möglich sein sollte. es scheint mir eher eine inkonsistenz im c++ standard zu sein. oder sieht hier jemand ein problem? leider hat man null einfluss auf den standard. 😞



  • da der funktionsaufrauf ansich von der signature her kompatibel sein muesste, da b von a abgeleitet ist, koennte man vielleicht auch einfach den funktionspointer casten.

    Meep Meep



  • ich muss zugeben, das ich da mit deinem beispiel code nicht so wirklich klar komme.
    koenntest du das konkret nochmal etwas genauer beschreibene, bzw an einem konkreten beispiel aufzeigen ?

    im grunde gesehen das gleiche nur halt mittels ner template-funktion wuerde es so auch gehen:

    class a
    {
    };
    
    class b : public a
    {
    
    };
    
    void f(a &A)
    {
    
    }
    
    template<typename T>
    class x
    {
    	public:
    		template<class func>
    		void f(func f)
    		{
    			T b;
    			f(b);
    		}
    };
    
    int main(void)
    {
    	x<b> X;
    	X.f(f);
    	return 0;
    }
    

    aber wie schon gesagt, bin ich mir nicht sicher, das ich ueberhaupt weiss was du genau willst.

    Meep Meep



  • im prinzip ist es recht einfach. mein code ist komplizierter als nötig, um das problem aufzuzeigen.

    gegenben sind eine basisklasse und eine klasse, die davon erbt. außerdem eine funktion, die als parameter eine refernz auf die basisklasse aufnimmt.
    will man nun einem funktionszeiger, der grundsätzliche die gleiche signatur hat, wie die gegebene funktion, mit dem einzigen unterschied, dass er statt der refernz zur basisklasse eine referenz zur abgeleitet klasse aufnimmt, diese gegebene funktion zuweisen, so klappt das nicht.
    es sollte aber klappen. rufe ich eine funktion, die als parameter eine beliebige basisklasse aufnimmt, mit einer instanz einer klasse, die von dieser basisklasse erbt, auf, so klappt es ja auch. dementsprechend wäre es eben schön, wenn das mit den funktionszeigern auch klappen würde.

    bei multipler vererbung könnte es vielleicht probleme geben. das muss ich mir noch überlegen. sonst sollte es möglich sein.



  • --- gestichen ---

    Die gleiche Lösung wie oben.

    Man sollte sich die Antworten doch noch einmal etwas Gründlicher ansehen...


Anmelden zum Antworten