Funktionsaufruf dynamisch gestallten.
-
Moin zusammen,
ich sitze hier gerade vor einem Problem. Ich muss eine Methode nutzen die so in der Headerdatei deklariert ist:
bool updateRowDB(DB * db, char * Table, ... )
D.h. die Anzahl der zu übergebenden Argumente ist variabel. Das ist auch ausprogrammiert und funktioniert so. Ich kann an dieser Methode nichts mehr ändern!
Nun muss ich diese Methode nutzen, ohne das ich selber an dieser Stelle weiß, ob ich nur ein weiteres Argument oder noch mehr übergebe (es sind Spalten einer DB Tabelle). Der Aufruf sieht also mal so:
slm->updateRowDB(getApp()->getDB(),"std_anmldbesch","anmld_serial","lfd_nr",NULL);
und mal so:
tableslm->updateRowDB(getApp()->getDB(),"std_anmldbesch",FL,"anmld_serial",NULL);
aus. Der NULL Wert schließt die Liste am Ende ab.
Wie kriege ich es nun hin, das ich nicht jeden theoretisch möglichen Funktionsaufruf ausprogrammiere?Ich weiß, das man das eleganter lösen könnte, wenn updateRowDB ein Array übergeben bekommt. Aber da kann ich nix ändern.
Im Moment mache ich es so, das ich einen Aufruf in der Form nutze:
tableslm->updateRowDB(getApp()->getDB(),feld[1],feld[2],...,feld[9]);
In dem Array feld[] steht standartmäßig NULL drinn und ich fülle es von vorne mit den Spaltennamen die ich übergeben bekomme. Da updateRowDB beim ersten NULL Wert das Ende der Liste erkennt, funktioniert das so. Aber wehe dem, ich habe mal mehr als 10 Spaltennamen ...
Ich hoffe ihr versteht mein Problem.
--
Martin
-
soweit ich den Standard verstehe, gibt es keine legale Möglichkeit.
das einfachste ist wohl du machst 10 overloads mit 1..10 parametern.Es gibt noch ein paar halbseidene tricks mit dem Stack, aber das wäre nur im äßersten Notfall anzuraten.
-
Auch Overloads in C++ lösen das Problem IMHO nicht
, denn wenn mehr als 10 Parameter übergeben werden sollen, fehlen die Funktionen/Methoden, die so viele Parameter akzeptieren. In C kann dagegen die selbe Funktion einmal 10 und einmal 20 Parameter annehmen
, ohne dass ISO C(99) etwas dagegen hat. In einem bestimmten Funktionsaufruf ist in C/C++ die Parameteranzahl zur Kompilierzeit bekannt (IMHO) und zur Laufzeit nicht zu verändern.
Ich hoffe, diese Information trägt zum besseren Verständnis und/oder zur Lösung des dargestellten Problems bei.
Mit freundlichen Grüßen
Hallo-C++
-
Hallo-C++ schrieb:
...
Ich hoffe, diese Information trägt zum besseren Verständnis und/oder zur Lösung des dargestellten Problems bei.Danke für Eure Infos ... dann werde ich wohl mal mit dem Entwickler der entsprechenden Klasse sprechen müssen ...
Martin
-
Nehmt statt dem ... einen vector<string> und alle sind glücklich
-
Nitram schrieb:
Wie kriege ich es nun hin, das ich nicht jeden theoretisch möglichen Funktionsaufruf ausprogrammiere?
Gibt es evtl. eine va_list Version der Funktion. Solche (...) Funktionen werden ja letztendlich auch nur darüber realisiert.
void foo(const char* format, ...) { va_list args; va_start(args, format); bar(format, args); va_end(args); }
Die bessere Möglichkeit ist dennoch, auf solche (...) Geschichten zu verzichten und stattdessen dynamische Arrays zu verwenden.
-
Auch Overloads in C++ lösen das Problem IMHO nicht , denn wenn mehr als 10 Parameter übergeben werden sollen, fehlen die Funktionen/Methoden, die so viele Parameter akzeptieren.
Hast du im prinzip recht, aber bei 20 Parametern würd' ich es nicht mehr verwenden wollen...
Nicht portable Lösung z.B. hier:
http://www.codeproject.com/Purgatory/va_pass.asp#xx1070712xx[edit]
Außerdem sollten alle, die (...) - Methoden ohne (va_list) - Variante implementieren, gesteinigt werden. [/edit]
-
Besteht die Möglichkeit, dass du mehrmals (in der Schleife) diese Funktion aufrufst?
-
peterchen schrieb:
Außerdem sollten alle, die (...) - Methoden ohne (va_list) - Variante implementieren, gesteinigt werden.
Könntest du mal so ein grobes Gerüsst einer va_list implementierung posten?
Martin
-
Hab ich nur so das Gefühl oder wird hier mal wieder versucht etwas möglichst kompliziert zu machen, statt den einfachen und direkten Weg zu gehen?
Bevor ihr hier auf solche hacks zurückgreift, sollte Martin lieber mal mit den Bibliotheksentwicklern sprechen, damit das ganze auf nen vector umgestellt wird.
Und erst wenn das fehl schlägt, dann könnt ihr über so etwas diskutieren.
-
ich hab mal meine c/c++-Referenz um Rat gefragt, da steht in etwa folgendes drin:
Die Implementierung von Funktionen mit beliebig vielen Argumenten beruht auf zwei Elementen:
double mittel(int anzahl, ...)
- Die Ellipse. Die ellipse in der Parameterliste ... zeigt an, dass bei Aufruf noch eine beliebige Zahl an Argumenten folgen kann. Die Ellipse muss am Ende der Parameterdefinition stehen, und ihr muss ein ordentlicher Parameter vorausgehen, an dem man innerhalb der Funktion ablesen kann, wieviele Parameter folgen.
- Die va_Makros aus <stdarg.h>. Diese werden benötigt, um die Argumente zu übernehmen und auszuwerten.
[..]
Die Benutzung der va_Makros entnehme man bitte einer eigenen Referenz, die Form wird hier aber nichts nutzen, da die Funktionsdeklaration keinen Parameter vorsieht, mit dem die Zahl der Argumente angegeben wird.
Es bestehet also nur die Alternative, die Deklaration zu ändern auf dynamische Arrays o.ä. oder auf eine fixe maximale Anzahl von Parametern durch überladen der Funktion.
-
User-- schrieb:
...
Bevor ihr hier auf solche hacks zurückgreift, sollte Martin lieber mal mit den Bibliotheksentwicklern sprechen, damit das ganze auf nen vector umgestellt wird.
Und erst wenn das fehl schlägt, dann könnt ihr über so etwas diskutieren.Du sprichst mir aus der Seele. Aber du kennst das bestimmt: Stelle dich vor eine Rauhfasertapete und sprich mit Ihr. Sie wird verständnissvoller sein ...
Ich werde es dennoch versuchen!
Martin
-
Dann sag deiner Rauhfasertapete, dass der Mist den sie da verzapft haben will kein C++ ist bzw, in C++ nicht umsetzbar ist. (Wie oben gesagt, der va_list-Krempel geht ja dank fehlender Mengenangabe auch nicht)
-
/edit: args doppelt abgeschickt
-
pumuckl schrieb:
Die Benutzung der va_Makros entnehme man bitte einer eigenen Referenz, die Form wird hier aber nichts nutzen, da die Funktionsdeklaration keinen Parameter vorsieht, mit dem die Zahl der Argumente angegeben wird.
Diesen Parameter brauchst du auch nicht. Und bei der momentanen Funktion ist der ja auch nicht vorhanden. Letztendlich ist das auch nicht die Aufgabe des Clients, sondern die Funktion selbst muss wissen, wieviele Parameter sie aus der va_list zieht. Dem Op ging es ja lediglich darum, eine dynamische Anzahl an Parametern zu übergeben, ohne für jede Variante eine separate Version zu schreiben. Und das ist mit va_list durchaus möglich.