Eleganter als überladen?



  • Hi,

    ich habe den Fall das ich in einer Prozedur eine Bestimmte
    Anzahl an Parametern erwarte. Diese können double oder ein pointer sein.
    Klassisch würde man das Problem mit überladen handeln, allerdings sind das
    bei 3 Parametern schon 8 Prozeduren.
    ich muss natürlich auch wissen ob der Parameter nu ein double oder pointer ist.
    Gibt es dort einen besseren Weg? evtl. Templates? Allerdings fällt mir da für meinen Fall auch keine Lösung ein.

    mfg
    Noxi



  • sehe ich das richtig dass du drei Parameter hast, die alle sowohl doubles als auch Pointer sein können?
    Wie kompliziert das wird hängt davon ab was du in Abhängigkeit von den untershiedlichen Typen machen willst. Skizziere mal bitte. Vielleicht gibts ja auch noch ne ganz andere Möglichkeit an die du noch nicht gedacht hast.



  • Du meinst, jeder Parameter kann entweder double oder ein Zeiger sein? Eine Möglichkeit wüsste ich gerade, allerdings würde ich gerne Genaueres über die Funktion erfahren, da es vielleicht bessere Alternativen gibt. Was soll die Funktion tun bzw. inwiefern können wahlweise Zeiger und double übergeben werden? Worauf zeigen die Zeiger? Sorry für meine Neugier... 😉



  • Wie wäre es denn, wenn du in jedem Fall einen Pointer übergibst, solwie drei Varibalen, die dir sagen ob der Pointer jetzt als Pointer auf die eigentlich gewollte double oder wirklich als Pointer gemeint ist. So in die Richtung:

    void function(double *p1, double *p2, double *p3, int i1, int i2, int i3){
        if(int i1=1){//(*p1) ist als double zu interpretieren
        }else{//p1 ist pointer
        }
        ...
        //and so on
    }
    

    Das als allgemeinen Lösungsansatz...
    Natürlich könnte es fallspezifisch auch noch eine einfachere, besser Lösung geben.



  • ichben schrieb:

    Wie wäre es denn, wenn du in jedem Fall einen Pointer übergibst, solwie drei Varibalen, die dir sagen ob der Pointer jetzt als Pointer auf die eigentlich gewollte double oder wirklich als Pointer gemeint ist. So in die Richtung:

    void function(double *p1, double *p2, double *p3, int i1, int i2, int i3){
        if(int i1=1){//p1 ist double
        }else{//p1 ist pointer
        }
        ...
        //and so on
    }
    

    Das als allgemeinen Lösungsansatz...
    Natürlich könnte es fallspezifisch auch noch eine einfachere, besser Lösung geben.

    "and so on" - genau. Man branched dann unnötig rum 😉



  • Ich denke boost::variant könnte das Problem halbwegs ellegant lösen, natürlich jenachdem was OP mit den Parametern vorhat.
    Siehe dazu http://www.boost.org/doc/libs/1_35_0/doc/html/variant/tutorial.html



  • Also, diese Funktion ist eine Initialisierung für ein Objekt.

    Als Beispiel:

    void init(double Param1; double Param2, etc ....) {
        _P1* = Param1;
        _p2* = Param2;
        ...
        }
    

    Nun möchte ich aber statt dem Wert einen Zeiger auf den Wert übergeben,
    da der Entsprechende Wert sich zur Laufzeit ändern kann.

    void (double Param1; double *pParam2,etc ....) {
    _P1* = Param1;
    P2 = pParam2;
    ...
    }
    

    In der Funktion müsste ich natürlich unterscheiden können ob es ein Zeiger ist, oder nicht.
    Ich weiß, ist etwas wirr... aber ich hoffe trotzdem verständlich...



  • Also ich verstehe dein Problem nicht so ganz verstanden bis jetzt. Das du irgendwelche Überladungen durch ein Template gerne vermeiden möchtest habe ich soweit kapiert. Aber nicht was du in der Funktion machen möchtest.

    Z.B. was sind den _P1, P2, _p2 für Variablen? Und woher kommen die?

    Da fehlt zu viel Kontext um einen guten Lösungsvorschlag anbieten zu können.



  • double get_value(double d) { return d; }
    double get_value(double* p) { return *p; }
    
    template<typename A, typename B, typename C>
    void func(A a, B b, C c) {
      double my_a = get_value(a);
      double my_b = get_value(b);
      double my_c = get_value(c);
    }
    

    Riecht aber wie eine Designkatastrophe...

    PS:
    was bedeutet "zur laufzeit sich ändern kann"?
    Du wirst doch wohl keine unsynchroniserten multithreaded zugriffe machen wollen? Und wenn du das nicht willst, dann ist die Aussage etwas zweifelhaft...


  • Mod

    weiße, schwarze oder bunte Pointer?



  • evilissimo schrieb:

    Also ich verstehe dein Problem nicht so ganz verstanden bis jetzt. Das du irgendwelche Überladungen durch ein Template gerne vermeiden möchtest habe ich soweit kapiert. Aber nicht was du in der Funktion machen möchtest.

    Z.B. was sind den _P1, P2, _p2 für Variablen? Und woher kommen die?

    Da fehlt zu viel Kontext um einen guten Lösungsvorschlag anbieten zu können.

    Sorry, die Dinger mit "_" sind private-Variablen der Klasse die mit dem Init initialisiert werden sollen.
    Zur Laufzeit macht eine periodisch aufgerufene Funktion der Klasse mit den Variablen irgentwas. Nu ist es aber so, das eineige Werte nicht "fest" bleiben, sondern sich laufen ändern. Um nicht jeder der X. Klassen wieder neu initilisieren zu müssen, dachte ich ich übergebe "wahlweise" einen Pointer auf eine Variable. so muss ich den Wert nur einmal ändern. Welcher Wert das aber im Einzelfall ist (der sich dynamisch ändern kann) weiss ich aber nur zur Laufzeit...


  • Mod

    sowas?

    struct proxy
    {
        double value;
        double* where;
        proxy(double value) : value(value), where(&this->value) {}
        proxy(double* where) : value(), where(where) {}
        proxy(const proxy& other) : value(other.value), where(other.where==&other.value?&this->value:other.where) {}
        proxy& operator=(double v) { *where = v; return *this; }
        operator double&() const { return *where; }
    private:
        void operator=(proxy&) const;
    };
    
    void init(proxy Param1; proxy Param2, etc ....).
    ...
    


  • Noxi schrieb:

    Also, diese Funktion ist eine Initialisierung für ein Objekt.

    Als Beispiel:

    void init(double Param1; double Param2, etc ....) {
        _P1* = Param1;
        _p2* = Param2;
        ...
        }
    

    Objekte initialisiert man mit dem Konstruktor. Shade of Mine hat recht, das riecht arg nach Designkatastrophe.

    Also hole mal bitte etwas weiter aus und erzähle uns was vom Kontext, vermutlich lässt sich dein Problem viel einfacher (und völlig anders) lösen.



  • Shade Of Mine schrieb:

    [cpp]
    PS:
    was bedeutet "zur laufzeit sich ändern kann"?

    Ich meine z.B. Messwerte 😉



  • Ok...ich hole aus...

    Also ich habe ein Sammelsurium an Klassen gleichen Basistyps in einer Liste , welche aneinandergereiht einen Ablauf ergeben. Erzeugt wird diese Liste dynamisch aus einem Script.

    In dem Script aus dem der Ablauf erzeugt wird stehen neben den entsprechenen Werten auch "Variablen" welche im Laufe der Abarbeitung Ihren Wert ändern können.

    z.B.

    aKlasse setzt einen Digitalen Ausgang
    bKlasse wartet 10 sekunden
    cKlasse Liest einen messwert.
    bKlasse wartet 10 sekunden
    cKlasse Liest einen messwert.
    cKlasse Liest einen messwert.

    mit dem Init sagen ich z.B. der a Klasse welchen Ausgang sie mit welchem Wert beschreiben soll, wenn sie an der Reihe ist...

    diese klassen werden in schleifen auch mehrfach aufgerufen.

    Nun kann es aber sein, das ich zum Zeitpunkt des Erzeugen des "Ablaufes" noch nicht weiss welcher Ausgang (Variable) das ist. Darum "wollte" ich der Klassen einen Pointer auf den Typ übergeben der dieses Information enhält, anstatt den Wert selbst. Ob das nun ein bitset oder int oder sonstwas ist.

    Ich hoffe es lichtet sich...


Anmelden zum Antworten