Template Fehler
-
so wie ich das sehe, geht das nicht mit templates! selbst spezialisierte templates helfen da nicht weiter. es bleibt ja nicht bei den beiden aufrufen (1 und 2), sondern es werden eben noch mehr.
Ich wollte nur die eigentliche Arbeit, die ja immer die gleiche ist, in eine seperate funktion verlegen und dann einen bestimmten wert zurückgeben.
Aber nun bleibt ja nichts anderes übrig, als für jeden fall eine eigene funktion zu schreiben!

vielen dank für eure hilfe
-
sheddy schrieb:
so wie ich das sehe, geht das nicht mit templates! selbst spezialisierte templates helfen da nicht weiter. es bleibt ja nicht bei den beiden aufrufen (1 und 2), sondern es werden eben noch mehr.
Ich wollte nur die eigentliche Arbeit, die ja immer die gleiche ist, in eine seperate funktion verlegen und dann einen bestimmten wert zurückgeben.
Aber nun bleibt ja nichts anderes übrig, als für jeden fall eine eigene funktion zu schreiben!

Wenn du uns erklärst was du wirklich machen möchtest und nicht irgendwelche unklaren Beispiele wie das obige lieferst, kann dir geholfen werden. Wenn nicht, dann musst du selbst weitertüfteln.
-
hmm..dachte das wäre klar gewesen - sorry.
Es soll eine Funktion angeboten werden, die einen Wert zurück gibt. Der Aufrufer der Funktion weiß den Datentypen des Rückgabewerts.
Der Aufrufer möchte zu einer Eigenschaft den Wert haben. Er weiß, dass der Typ der Eigenschaft "int" ist. Also ruft er "int getInt(string)" auf. Möchte er den Wert einer Eigenschaft, die den Typ "float" hat, so ruft er die Funktion "float getFloat(string)" auf.
Mein Versuch war es nun, da vieles in der Funktionen gleich ist und sich nur der Wert, der am Ende zurückgegeben werden soll, sich verändert (float, int, double, etc.) wollte ich alles in EINE Funktion stecken.
Der zweite Parameter meiner template-Funktion sollte den Typen des Datentypen spezifizieren, den ich in der Funktion mit einer Abfrage (if-selse, switch ...) abfragen würde und dementsprechend dann den gewünschten Wert mit dem entsprechenenden Datentypen zurückgebe.
Im Ganzen:
Statt
int getInt(string);
float getFloat(string);soll
*bestimmter Datentyp* getVal(string, int)
ich hoffe, es ist ein wenig klarer geworden.
mfg
-
Sprich, du brauchst so etwas wie den Datentyp Variant? Eine solcher Datentyp Variant kann verschiedene Datentypen aufnehmen. Siehe auch: http://de.wikipedia.org/wiki/Variant und http://www.gamedev.net/reference/articles/article2029.asp .
Gruß Kimmi
-
sheddy schrieb:
hmm..dachte das wäre klar gewesen - sorry.
Es soll eine Funktion angeboten werden, die einen Wert zurück gibt. Der Aufrufer der Funktion weiß den Datentypen des Rückgabewerts.
Der Aufrufer möchte zu einer Eigenschaft den Wert haben. Er weiß, dass der Typ der Eigenschaft "int" ist. Also ruft er "int getInt(string)" auf. Möchte er den Wert einer Eigenschaft, die den Typ "float" hat, so ruft er die Funktion "float getFloat(string)" auf.
Mein Versuch war es nun, da vieles in der Funktionen gleich ist und sich nur der Wert, der am Ende zurückgegeben werden soll, sich verändert (float, int, double, etc.) wollte ich alles in EINE Funktion stecken.
Der zweite Parameter meiner template-Funktion sollte den Typen des Datentypen spezifizieren, den ich in der Funktion mit einer Abfrage (if-selse, switch ...) abfragen würde und dementsprechend dann den gewünschten Wert mit dem entsprechenenden Datentypen zurückgebe.
Im Ganzen:
Statt
int getInt(string);
float getFloat(string);soll
*bestimmter Datentyp* getVal(string, int)
ich hoffe, es ist ein wenig klarer geworden.
mfg
Das geht mit
void *als Rückgabetyp. Allerdings musst du dann jedes mal eine Typ-Umwandlung vornehmen.
-
ich kannte den typen bis eben noch nicht, ABER genau sowas brauche ich

aber anscheinend gibt es sowas nicht in C bzw. C++. Und Zeiger hin- und hercasten wollte ich eigentlich vermeiden.
trotzdem danke für die hilfe....
-
Wo ist in deinen Augen der Unterschied zwischen
int getInt(string); float getFloat(string);und
template <typename T> T get(string);?
Du kannst es dann je nachdem was du brauchst mit get<int>("bla"), get<string>("blubb") usw. aufrufen.
Allerdings ist das alles relativ witzlos wenn du dann eh die ganze Funktion nur als großen switch baust - im Grunde hast du dann nämlich sowas:
template<typename T> T getValue(string foo){ switch(/*type-abhängige konstante*/){ case /*Int-ID*: return getInt(foo); case /*String-ID*/: return getString(foo); } }und landest am Ende doch wieder bei getInt, getString usw.
-
Ein Beispiel:
#include <iostream> #include <string> enum Type { TYPE_INT, TYPE_STRING }; void *myFunction(Type type) { switch (type) { case TYPE_INT: return new int(100); break; case TYPE_STRING: return new std::string("Hey!"); break; } return NULL; } int main() { void *ptr = myFunction(TYPE_INT); if (ptr != NULL) { std::cout << *(int *)ptr << std::endl; } delete ptr; ptr = myFunction(TYPE_STRING); if (ptr != NULL) { std::cout << *(std::string *)ptr << std::endl; } delete ptr; }Wird allerdings sehr spaßig (Casting, Speicherfreigabe).
-
Ich werfe mal noch boost::any in den Raum.
-
Fassen wir das nochmal zusammen:
- Du hast Benutzer, die Werte haben wollen.
- Die Benutzer wissen, was sie haben wollen.
- Es gibt einen Teil, der für jeden Rückgabewert immer gleich ist.
- Es gibt einen Teil, der unterscheidet sich aufgrund des Rückgabetypen.
Hättest Du unterschiedliche Funktionen, würde der Benutzer ja wissen, welche Funktion er aufrufen müsste (siehe Punkt 2).
Wieso dann nicht so?ReturnType somethingCommonForAll(...){...} float getFloat(...) { //... ReturnType var = somethingCommonForAll(...); //... return floatVal; } int getInt(...) { //... ReturnType var = somethingCommonForAll(...); //... return intVal; } //usw.
-
Tachyon hat verstanden, was ich meine! genau so! bei pumuckls lösung ist eben genau dieses "/*type-abhängige konstante*/" das problem! der funktion muss ja schon eine art signal mitgegeben werden, um welchen typ es sich handelt.
und dann funktioniert schon nicht mehr der explizite aufruf der template funktion.und so wie ich das die letzten posts gesagt habe und tachyon vorgeschlagen hat, habe ich es auch jetzt gemacht! im endeffekt auch sinnvoller für den benutzer, der dann die genaue funktion aufruft!
Hättest Du unterschiedliche Funktionen, würde der Benutzer ja wissen, welche Funktion er aufrufen müsste (siehe Punkt 2).
Und da habe ich gedacht, dass EINE funktion reichen würde, die alles bearbeitet. so muss ich jetzt in jeder funktion den "gleichen" quellcode benutzen. im groben und ganzen unterscheiden sich die funktionen kaum - eben bis auf den rückgabewert.
ich arbeite mit den xml-frameworks xerces und xalan und da muss vorher ein wenig mehr vorarbeit geleistet werden, um dann eine gezielte funktion zu nutzen und wollte die arbeit auf eine funktion beschränken!
daher auch mein recht kurzes beispiel am anfang des threads, um den ganzen "rattenschwanz" der xml-frameworks rauszulassen.Im ganzen war es eigentlich eine "optimerung" bzw. faulheit meinerseits

-
sheddy schrieb:
Im ganzen war es eigentlich eine "optimerung" bzw. faulheit meinerseits

Das Vermeiden von doppeltem Code ist allgemein sehr sinnvoll, weil es Änderungen erleichtert und Fehler beim Duplizieren gar nicht erst auftreten können. Das man zusätzlich noch Schreibarbeit spart ist natürlich auch ein willkommener Effekt

-
danke, das wollte ich sagen
