Vektor von Funktionen



  • Hallo!

    ich hab folgendes Problem:
    Ich habe bereits eine Struktur Vector:

    struct Vector{
    int length;
    double * data;
    };

    schön. jetz hätte ich aber gerne einen Vektor von Funktionen, anstatt von doubles.
    Wie könnte ich das machen?

    vielen Dank im Voraus.

    Oliver.



  • a) warum nimmst du nicht einfach den std::vector?
    b) für größen Angaben solltest du std::size_t nehmen

    für Funktionen kannst du Funktionspointer nehmen.

    Ich würde an deiner Stelle aber boost::function (www.boost.org) benutzen, dann hast du nen schönen Wrapper, der auch Member-Pointer unterstützt usw.



  • #include <stdio.h>
    
    typedef void (*func_t)(void); // du kannst aber auch andere parametertypen und rückgabetypen benutzen
    
    struct Vector
    {
    	int length;
    	func_t* data;
    };
    
    void func1(void)
    {
    	printf("func1\n");
    }
    
    void func2(void)
    {
    	printf("func2\n");
    }
    
    void main(void)
    {
    	struct Vector funcs;
    
    	funcs.length = 2;
    	funcs.data = new func_t [funcs.length];
    
    	funcs.data[0] = func1;
    	funcs.data[1] = func2;
    
    	for (int i = 0; i < funcs.length; i++)
    	{
    		funcs.data[i]();
    	}
    
    	delete [] funcs.data;
    }
    


  • Danke erst mal für eure Hilfe!
    Das ganze funktioniert jetzt mal so im großen und ganzen, ich will aber noch was ändern:
    und zwar hätt ich gern, daß ich nicht für jedes i extra schreiben muss:

    funcs.data[0] = func1;
    funcs.data[1] = func2; usw.

    sondern z.b., daß funci = sin(5*i);
    dachte dabei daran, daß func irgendwie so aussieht:

    double func(double x, double i){
    return Sin(x*i);
    }

    nun kann ich dieses func aber nicht mehr so einfach in meinen Vektor reinschreiben, oder??



  • wozu brauchst du dann einen vector?

    for(int i=0; i<10; ++i)
      func(i*5);
    

    Du musst uns schon erklären was du willst...



  • okay.. da hatte ich wohl nen gewissen denkfehler 😕

    danke trotzdem.



  • hallo!
    nochmal ich *g*
    also.. es war wohl doch kein denkfehler..
    ich erklärs am besten etwas ausführlicher:

    ich hab die Funktion:

    double Integrate(double(*f)(double),int n,double h){
       double Ergebnis=0;
       double sum=0;
       for (int i=1; i<n; i++){
         sum=sum+(f((double)i/n));
        }
       Ergebnis=(1./(2*n))*h*(f(0.)+f(1.))+(1./n)*sum;
       return Ergebnis;
    }
    

    kann hier also, wenn ich diese Funktion aufrufe, hier nur f ohne parameter reinschreiben:z.B.:
    Integrate(func,5,0.2);

    daher kann ich aber, wenn func wie in meinem vorigen posting ist, das hier wohl nicht reinschreiben (selbst wenn ich in der Funktion Integrate f mit 2 parametern reinschreiben würde).

    oder kann ich einen aufruf machen von der Art (nehme an,f bei Integrate hätte 2 parameter):

    Integrate(func(double,1),5,0.2);

    ??

    Da ich dachte, daß das nicht geht, is mir das mit dem Funktionenvektor eingefallen, da ja dann wieder jede Funktion nur von einem double abhängt.

    Integrate(func.data[1],5,0.2);

    hoffe, daß das jetzt verständlich ist und nicht allzu kompliziert geschrieben ist 😃



  • Functors:

    class functor
    {
    private:
      int i;
    public:
      functor(int i) : i(i) {}
      double operator()(double d)
      {
        return d*i;
      }
    };
    
    template<class Func>
    double Integrate(Func f, int n, double h)
    {
       double Ergebnis=0;
       double sum=0;
       for (int i=1; i<n; i++){
         sum=sum+(f((double)i/n));
        }
       Ergebnis=(1./(2*n))*h*(f(0.)+f(1.))+(1./n)*sum;
       return Ergebnis;
    }
    
    int main()
    {
      cout<<Integrate(functor(3), 3, 7.3);
    }
    

    das Prinzip verstanden?

    Es nennt sich functor.
    Wenn man den operator() überlädt, kann man mittels f() diesen aufrufen. f sieht also aus wie eine normale Funktion.
    Allerdings kann f, da es ja eine Klasse ist, auch einen status speichern. also zB i



  • ja, danke. verstanden hab ichs.
    ohne klassen kann man das wohl offensichtlich leider nicht machen.
    werd ich wohl mal in den sauren apfel beissen.

    danke jedenfalls.


Anmelden zum Antworten