variable argumenteliste bei funktionen



  • Ohne zu wissen, wieviele Argumente da kommen werden, wird es nicht gehen. Und klar, der Benutzer kann sich verzählen und eine andere Anzahl übergeben als angegeben. Deshalb ist printf ja auch so unsicher, da der Compiler keine Möglichkeit hat festzustellen, ob die Anzahl stimmt.

    Als mögliche Lösungsansätze in C++ könnte man Präprozessormetaprogrammierung (bei boost sehr häufig zu finden) oder ab C++09 variadic Templates heranziehen.



  • LordJaxom schrieb:

    Als mögliche Lösungsansätze in C++ könnte man Präprozessormetaprogrammierung (bei boost sehr häufig zu finden) oder ab C++09 variadic Templates heranziehen.

    Bitte was? 😕



  • folgende Moeglichkeiten fallen mir ein:
    - uebergib einen 2D-vector (also vector<vector<double> >), die erste Dimension ist die Anzahl der variablen, die zweite dimension jeweils der Grad des Polynoms+1, die Inhalte sind die Koeffizienten. bsp:

    f(x,y) = 2.5x2+3x+5+1.2y3

    5  3  2.5   //3 koeffizienten fuer den x-polynom 2ten grades
           1.2  0  0   0    //4 koeff fuer den y-polynom 3ten grades
    

    Oder du uebergibst die funktionen im Klartext als String und schreibst dir einen Parser dafuer.

    Auf jeden Fall kannst du aber immer einen vector uebergeben und size() aufrufen um die Zahl der ARgumente zu erfahren.



  • genau das wollte ich ja grad nicht, dass der user die argumente extra noch in einen vector oder ein array packen muss. und meine polynome sind im algebraischen sinne gemeint, dh mit double ist da nicht viel, das ist zu spezifisch.
    polynome haben bei mir 3 verschiedene typen, nämlichen ergebnis, koeffizienten und argumente typ. mal abgesehen davon müssen die monome des polynoms nicht nur aus einer variable bestehen.



  • FreakyBKA schrieb:

    Bitte was? 😕

    Man kann mit dem Präprozessor Funktionen mit wachsenden Parameterlisten erzeugen lassen. Sieht aber fürchterlich hässlich aus und erzeugt Unmengen an Code. Außerdem muss man die höchste Anzahl der Parameter zuvor festlegen.

    Alle drei Nachteile werden in C++09 durch ein elegantes Sprachmittel ausgeglichen: Variadic Templates (gegen das 😕 hilft hier Google und der Artikel im Magazin dieses Forums)



  • FreakyBKA schrieb:

    ...polynome haben bei mir 3 verschiedene typen, nämlichen ergebnis, koeffizienten und argumente typ. mal abgesehen davon müssen die monome des polynoms nicht nur aus einer variable bestehen.

    Ich möchte mal sehen wie du verschiedene Typen etc. relativ sicher in einer variablen Argumentenliste übergibst... Nur ein Parameter falsch übergeben wirst du sicherlich in Abstürze geraten können.

    Kontainer haben auf jedenfall den Vorteil das sie typsicher und weitgehend unproblematisch sind. Falls dir das Füllen von Kontainern zu aufwendig erscheint, solltest du dir mal die Boostbibliothek anschauen, die hat dafür eine verkürzte Schreibweise (dank überladung des ","-operators ...).

    cu André



  • also die drei verschiedenen typen stehen schon bei der definition des polynoms fest, d.h. sie werden als template-argumente übergeben. z.B. polynom<float, int, char> würde bei mir bedeuten, dass das polynom als ergebnis einen float-wert liefert, als koeffizienten int-werte hat und die argumente sind char-werte. was die polynomklasse dann intern damit macht ist irrelevant.

    polynom<float, int, char> p;
    char x = 'a', y = 'b', z = 'c';
    //allg.: char x_1, ..., x_n
    float f, g;
    g = p(x,y);
    f = p(x,y,z);
    //allg.: f = p(x_1, ..., x_n);
    

    so ist das gemeint, ich hoffe das es jetzt halbwegs verständlich ist. somit haben alle argumente den gleichen typ, der auch von anfang an feststeht.



  • FreakyBKA schrieb:

    ...somit haben alle argumente den gleichen typ, der auch von anfang an feststeht.

    ...aber nicht durch das Typsystem von C++ gewährleistet ist. Korrigiert mich bitte, aber soviel ich von Elipsen weiß können die Parameter beliebigen Typs sein (oder anders formuliert: es wird keine Typüberprüfung für variable Parameter gemacht).

    cu André



  • das weiß ich ja und darum gehts ja auch nicht, sondern darum woher ich weiß wieviele argumente übergeben werden. bei den va_* kram hab ich nichts der art gefunden. bei printf funktioniert das ja auch, wenn ich zuwenig zusätzliche parameter angebe, dann meckert er rum.



  • wie stellst du dir das eigentlich mit der benutzung deiner klasse vor ?
    soll der benutzer für jedes poynom ein extra kompilat anfertigen ? 😕



  • FreakyBKA schrieb:

    bei printf funktioniert das ja auch, wenn ich zuwenig zusätzliche parameter angebe, dann meckert er rum.

    printf liefert die Anzahl indirekt über den Formatstring. Die Kontroller führt aber der Compiler nur so durch, im Standard ist sie nicht enthalten. Ein kostenloser Service. 😉



  • In C werden alle übergebenen Variablen einfach nur auf den Stack gepusht. Eine Funktion weiss _nie_ wieviele Parameter sie wirklich übergeben bekommen hat.

    Deshalb muss in C jedesmal der Caller den Stack aufräumen. Was du willst ist technisch nicht sauber möglich.



  • Hi,

    ich verstehe nicht, was ein Buchstabe ("char") in einem Polynom zu suchen hat.
    Insgesamt scheint mir, dass Du noch nicht wirklich weißt, was Du da implementieren willst ... 😉
    Für variable Parameterlisten gibt's immer noch prima den std::vector - der ist prima.
    und wenn Du pro Term mehrere Angaben machen möchtest (Parametername, exponent, Wert, ...) kannst Du die gut in einen struct packen, der dann in den vector wandert.

    Gruß,

    Simon2.



  • also ich weiß schon was ich implementieren will, weil es bis auf die Sache mit der variablen Parameterliste schon alles implementiert ist. Das mit dem char war nur ein Beispiel um das Prinzip zu erklären.
    Die Idee ist einfach das man allg., wie in der Algebra, Polynome über bestimmten Ringen definieren kann. Somit könnte man als Templateargumente eigene Klassen übergeben, die die Ringeigenschaften erfüllen und schon hat man den Polynomring dazu. Sowas ist natürlich nur für Leute wie mich als Mathematiker interessant. Und ich wollte halt wissen ob es variable Argumentlisten dieser Art gibt, was aber offensichtlich nicht so ist. Die alternative Übergabe mit einem Array ist schon implementiert, aber muss der User dafür halt extra ein Array deklarieren. Letztendlich ist es nur Schönheitskorrektur und wäre schön gewesen wenn es ginge.



  • FreakyBKA schrieb:

    Letztendlich ist es nur Schönheitskorrektur und wäre schön gewesen wenn es ginge.

    sicher geht das. variable anzahl von argumenten kann man als zeiger übergeben.
    oder du übergibst eine zeichenkette der form "a0*x^0 + a1*x^1 + a2*x^2 + ... + an*x^n"
    die du dann parsen kannst.
    der vorteil bei der zeichenkette ist ganz klar:
    es können mehrere xn an unterschiedlichen positionen auftauchen.
    variabler geht es nicht.
    der aufwand fürs parsen ist relativ gering, du hast nur zwei operatoren und zahlenwerte.



  • agga ugga schrieb:

    "a0*x^0 + a1*x^1 + a2*x^2 + ... + an*x^n"

    wenn die Polynome denn so einfach wären 😉
    ein allg. Polynom besteht aus einer endlichen Summe von Termen, die wiederum das Produkt eines Koeffizienten und endlich vielen Variablen sind.
    Die Parameter bestimmen dann den Wert den die jeweiligen Variablen annehmen sollen.
    Da als Parameter wie gesagt potentiell beliebige Klassen möglich sind, fällt da meines erachtens ein String als Parameter raus.





  • also der artikel beschreibt zwar eine möglichkeit, wie man beliebige argumentlisten erzeugen kann, jedoch stört mich die form, dass man jedes argument klammern muss. und da es hier wie gesagt nur um ästhetik und bequemlichkeit geht, ist das nicht passend.
    also nochmal ich möchte etwas folgender art machen können

    polynomial p;
    //...
    p(1,2);
    p(0,7,3);
    p(2,25, ...);
    


  • FreakyBKA schrieb:

    also nochmal ich möchte etwas folgender art machen können

    Und nochmal:
    das geht so nicht.

    Man kann nur etwas aehnliches erreichen.



  • schade halt 😃


Anmelden zum Antworten