Rückgabetyp einer Funktion variabel bestimmen?
-
Das willst du nicht wirklich (außer zum rumspielen).
Wenn die Rückgabe variabel sein soll und der Aufrufer weiß was zurückgeliefert wird, dann verwende dafür boost::any
-
Oder den guten alten void*, da kann alles dahinter sein. Musst aber wissen er den speicher freigibt.
PS: boost ist kein schöner name, klingt so angeberisch.
-
funktionstemplate
template <typename T> T foo(T x) { /*code....*/ return x; }
-
die unschönste mögliche alternative ist dann:
(so würd ichs machen wenn ich keine andre möglichkeit hätte)
is eig scheisse/langsam aber kreativ:struct RETURNVALUE { int whichvalue; float valuef; char *valuec; int valuei; } RETURNVALUE funktion { RETURNVALUE back; if(bedingung 1(string zurück)) { back.valuef = 0; back.valuec = deinstring; back.valuei = 0; back.whichvalue = 2; return back; } if(bedingung 2(int zurück)) { back.valuef = 0; back.valuec = NULL; back.valuei = deininteger; back.whichvalue = 3; return back; } ...usw
-
try catch throw hack, sehr unsauber
sag was du machen willst
-
Naja, es gibt boost::variant und boost::any - damit lässt sich viel abdecken wenns nicht schnell sein muss.
Wenns um einfache Werte geht (also keine Klassentypen oder so) dann u.U. einfach nen String zurückgeben?
-
maybe schrieb:
funktionstemplate
template <typename T> T foo(T x) { /*code....*/ return x; }Das kann man auch mit normalem Overloading ohne templates machen .. ich denke aber, der OP möchte aber identische Aufrufparameter.
Gruß,
Simon2.
-
Unter COM gibt es Variants, unter Qt gibt es die QVariant. So eine Variant kann als Inhalt jeden integralen Typen haben. Wenn du auf keine vordefinierten Variants hast, schreibe dir einfach selber eine -ist nicht schwer:
Du musst dir in einer Member den Typ merken, als enum halt. Und ansonsten hast du noch eine Union mit den entsprechende Typen. Und dann noch ein paar convenience-Funktionen um die Variant je nach Typ in ein float/int/double... zu konvertieren.
Schau dir doch mal das Interface von QVariant an:
http://doc.trolltech.com/qtopia4.2/qvariant.htmlmugglemaster
-
Besten Dank für die Zahlreichen Tips

Das sieht schon mal sehr gut aus. Ich werde mir alles noch mal genauer anschauen

-
spakko schrieb:
...Ich werde mir alles noch mal genauer anschauen

Tu das.
Schaue Dir aber auch nochmal genau an, wofür Du das eigentlich zu brauchen meinst. Ich kenne das eigentlich nicht, dass Funktionen völlig verschiedene Dinge zurückgeben müssen. Wenn die Dinge keinerlei Gemeinsamkeit haben, weiß ich nicht, ob es wirklich "dieselbe Funktion" ist.Der Aufrufer muss (meist) sowieso hinterher herausbekommen, welchen Typ er da in der Hand hält ... je länger man diese "Ungewissheit" aufrecht erhalten will, desto komplexer wird das Ganze - oftmals vollkommen überflüssig.
Gruß,
Simon2.
-
Simon2 schrieb:
maybe schrieb:
funktionstemplate
template <typename T> T foo(T x) { /*code....*/ return x; }Das kann man auch mit normalem Overloading ohne templates machen .. ich denke aber, der OP möchte aber identische Aufrufparameter.
Gruß,
Simon2.
nur mal so zur info..
ne das geht nicht .. weil bei overloading von funktionen/methoden der Rückgabewert nicht dazu gehört.
-
maybe schrieb:
Simon2 schrieb:
maybe schrieb:
funktionstemplate
template <typename T> T foo(T x) { /*code....*/ return x; }Das kann man auch mit normalem Overloading ohne templates machen .. ich denke aber, der OP möchte aber identische Aufrufparameter.
Gruß,
Simon2.
nur mal so zur info..
ne das geht nicht .. weil bei overloading von funktionen/methoden der Rückgabewert nicht dazu gehört.Aber ganz sicher geht das (was da mit dem Funktionstemplate gemacht wurde) genauso mit overloading, obwohl der Rückgabewert nicht dazugehört (was mir bekannt war). :p
Gruß,
Simon2.
-
ne ist nicht so weil ich als rückgabewert
template <typename T>
T foo(T x)
{
/*code....*/
return x;
}habe und wenn du das versuchen würdest zu überladen hättest du ein dickes problem.
-
maybe schrieb:
ne ist nicht so weil ich als rückgabewert
template <typename T>
T foo(T x)
{
/*code....*/
return x;
}habe und wenn du das versuchen würdest zu überladen hättest du ein dickes problem.
Ich glaube, Du übersiehst das Wesentliche:
template <typename T>
T foo(T x)
{
/*code....*/
return x;
}Und genau deswegen geht das auch mit Overloading !
Gruß,
Simon2.
-
Da du aber 2x den gleichen Typ hast koenntest du auch die Funtkionen ueberladen
string foo(string s);
int foo(int i);Aber der Threadersteller woltle wohl eher sowas wie
template<class T> T foo(int i);oder so, denke ich.
-
mir geht es nicht um die parameterliste!!
mir geht es hier um den rückgabewert!!!
und wenn ich mich recht ensinne war seine frage wir er was zurückgeben kann und das geht nun mal mit overloading nicht..und in dem thread geht es ja "Rückgabetyp einer Funktion variabel bestimmen?" ..
gruss
maybe :xmas1:PS: frohes Fest trotzdem

-
Shinja schrieb:
...
Aber der Threadersteller woltle wohl eher sowas wietemplate<class T> T foo(int i);oder so, denke ich.
Das meinte ich mit
Simon2 schrieb:
.. ich denke aber, der OP möchte aber identische Aufrufparameter.
Gruß,
Simon2.

Gruß,
Simon2.
-
genau Shinja .. das wollte ich eigentlich sagen, ok mein Beispiel war wohl nicht irreführend..
-
Simon2 schrieb:
spakko schrieb:
...Ich werde mir alles noch mal genauer anschauen

Tu das.
Schaue Dir aber auch nochmal genau an, wofür Du das eigentlich zu brauchen meinst. Ich kenne das eigentlich nicht, dass Funktionen völlig verschiedene Dinge zurückgeben müssen. Wenn die Dinge keinerlei Gemeinsamkeit haben, weiß ich nicht, ob es wirklich "dieselbe Funktion" ist.Der Aufrufer muss (meist) sowieso hinterher herausbekommen, welchen Typ er da in der Hand hält ... je länger man diese "Ungewissheit" aufrecht erhalten will, desto komplexer wird das Ganze - oftmals vollkommen überflüssig.
Gruß,
Simon2.
Nur mal so ne Überlegung, was daraus werden soll:
DBase db("DNS"); db.Connect(); RSet rs(db.Execute("SQL-Irgendwas...")); rs.MoveFirst(); do { cout << rs.Fields("COL-Irgendwas").Value() << endl; } while(rs.MoveNext()); rs.Close(); db.Close();Spakko :xmas1:
-
Spakko schrieb:
...
Nur mal so ne Überlegung, was daraus werden soll:DBase db("DNS"); db.Connect(); RSet rs(db.Execute("SQL-Irgendwas...")); rs.MoveFirst(); do { cout << rs.Fields("COL-Irgendwas").Value() << endl; } while(rs.MoveNext()); rs.Close(); db.Close();Spakko :xmas1:
Sowas hatte ich befürchtet.

OK, da braucht man wirklich ein Konzept "generischer Typen".
Wir hatten da einen Externen in unserer Firma, der hatte etwas Vergleichbares geschrieben ... und es war sehr gut ... und seeeehr aufwendig !Als Erstes solltest Du Dir überlegen, wann und wie die Typinformation der DB in Dein Programm übergeben werden: Zur Compile-/Link/-Laufzeit ?
Je früher, desto "entspannter" kannst Du generisch programmieren (unaufwendiger, sicherer, ...).Außerdem musst Du Dir überlegen, welce DB-interne Strukturen (Schlüsselbeziehungen, delete-Rules, Joins, Nullables, ....) Du nach Außen nutzbar machen möchtest ... und wie Du das abbildest.
Schließlich: Denke bei Deinen Entscheidungen nicht nur an Deine Schnittstelle, sondern auch an den armen Programmierer, der das nutzen muss - und daran, dass Du vermutlich in Konkurrenz zu "DB-eigenen APIs" (SQL, ...) stehst.
Wenn Deine Schnittstelle komplizierter zu nutzen ist als diese, wird sie sich kaum durchsetzen.Naja, Du hast ja schon einiges zum Lesen und rumprobieren bekommen.
Frohe Weihnachten wünscht,
Simon2.