Template mit Default Parameter mit Default Initialiserung in C++

cockroad

Mitglied
Hallo zusammen.
ich hoffe es kann mir jemand helfen. Ich habe folgendes Problem:
Ich möchte ein Template erzeugen, dass mir Variablen mit unterscheidlichen Typ (CString, int, float) mittels typename verarbeitet. Ich habe insgesamt 4 mögliche Variablen, jedoch können auch mal weniger vorkommen. Mein template sieht derzeit ungefähr so aus:
template <typename T1, typename T2,typename T3, typename T4>
meine Funktion in der ich dieses Template verwende so:
Funktion abc(T1 var1, T2 var2, T3 var3, T4 var4).
Ich habe es schon z.B. mit T4 var4 = T4(0) probiert, aber der Kompiler sagt für Ergebnisse mit z.B. nur 3 Variablen, dass keine überladene Funktion nur 3 Argumente nimmt.
Ich habe mich noch nie mit Templates vorher beschäftigt.
Danke im Vorraus für die Hilfe.
 
Hi,

das Thema wird ins entsprechende Board verschoben, denn das interne "Feedback"-Forum bezieht sich auf "tutorials.de".
 
Hi.
Hallo zusammen.
ich hoffe es kann mir jemand helfen. Ich habe folgendes Problem:
Ich möchte ein Template erzeugen, dass mir Variablen mit unterscheidlichen Typ (CString, int, float) mittels typename verarbeitet. Ich habe insgesamt 4 mögliche Variablen, jedoch können auch mal weniger vorkommen. Mein template sieht derzeit ungefähr so aus:
template <typename T1, typename T2,typename T3, typename T4>
meine Funktion in der ich dieses Template verwende so:
Funktion abc(T1 var1, T2 var2, T3 var3, T4 var4).
Ich habe es schon z.B. mit T4 var4 = T4(0) probiert, aber der Kompiler sagt für Ergebnisse mit z.B. nur 3 Variablen, dass keine überladene Funktion nur 3 Argumente nimmt.
Das ist auch richtig. Die Funktion ist eine Template-Funktion und existiert noch nicht als Instanz. Bei der Instanzierung (die explizit und implizit erfolgen kann) deduziert der Compiler den Typ der Parameter und setzt ihn an die Stelle der Template-Typen. Wenn du nur 3 Argumente übergibst, kann der Compiler logischerweise für den vierten Parameter den Typ nicht bestimmen. Und für einen unbekannten Typ gibt es auch keinen Standardwert der als Standardparameter übergeben werden könnte.

Du kannst dem Compiler natürlich auf die Sprünge helfen und direkt angeben welche Typen die Parameter haben:
C++:
template <typename T1, typename T2,typename T3, typename T4>
void abc(T1 var1, T2 var2, T3 var3 = T3(), T4 var4 = T4()) {
  ...
}

abc<int, int, double, int>(1, 2);
Gruß
 
Hi.
Das ist auch richtig. Die Funktion ist eine Template-Funktion und existiert noch nicht als Instanz. Bei der Instanzierung (die explizit und implizit erfolgen kann) deduziert der Compiler den Typ der Parameter und setzt ihn an die Stelle der Template-Typen. Wenn du nur 3 Argumente übergibst, kann der Compiler logischerweise für den vierten Parameter den Typ nicht bestimmen. Und für einen unbekannten Typ gibt es auch keinen Standardwert der als Standardparameter übergeben werden könnte.

Du kannst dem Compiler natürlich auf die Sprünge helfen und direkt angeben welche Typen die Parameter haben:
C++:
template <typename T1, typename T2,typename T3, typename T4>
void abc(T1 var1, T2 var2, T3 var3 = T3(), T4 var4 = T4()) {
  ...
}

abc<int, int, double, int>(1, 2);
Gruß

hi deepthroat,
danke für die Info. Werde ich mal versuchen!!

Grüsse
 
hi deepthroat,
danke für die Info. Werde ich mal versuchen!!

Grüsse

Hallo,
also so ganz funktioniert das nicht. Ich muss folgendes machen:
ich habe 13 mal die gleiche Funktion, jedoch werden dieser Funktion immer unterschiedliche Variablen bzw. Variablentypen übergeben, so sieht das aus:
void abc(CString var1, CString var2);
void abc(CString var1, CString var2, CString var3);
void abc(CString var1, CString var2, int var3);
void abc(CString var1, CString var2, CString var3, CString var4);
void abc(CString var1, CString var2, int var3, int var4);
void abc(CString var1, CString var2, CString var3, int var4);
void abc(CString var1, int var2, CString var3, int var4);
void abc(CString var1, CString var2, int var3, CStringvar4);
void abc(CString var1, CString var2, CString var3, CString var4, CString var5);
void abc(CString var1, CString var2, CString var3, CString var4, int var5);
void abc(CString var1, int var2, CString var3, CString var4, int var5);
void abc(CString var1, CString var2, int var3, int var4, int var5);
void abc(CString var1, CString var2, CString var3, CString var4, CString var5, CString var6 );
void abc(CString var1, CString var2, int var3, int var4, int var5, int var6);
void abc(CString var1, CString var2, CString var3, CString var4, CString var5, CString var6, CString par5);
void abc(CString var1, CString var2, CString var3, CString var4, CString var5, CString var6, int var7);
void abc(CString var1, CString var2, int var3, int var4, int var5, int var6, int var7);
void abc(CString var1, int var2, CString var3, int var4, CString var5, float var6);

var 1 ist immer vom selben Typ, deswegen definiere ich ihn gleich fest, jedoch dann geht es los und ich hab mir gedacht deswegen ein Template zu benutzen
Kann mir da jemand weiter helfen?
Und noch ne Frage: ich habe Header und cpp-File, wo mach ich was
 
Zuletzt bearbeitet:
Hi.
Hallo,
also so ganz funktioniert das nicht.
Doch, nur so funktioniert es überhaupt.
Ich muss folgendes machen:
ich habe 13 mal die gleiche Funktion, jedoch werden dieser Funktion immer unterschiedliche Variablen bzw. Variablentypen übergeben, so sieht das aus:
void abc(CString var1, CString var2);
void abc(CString var1, CString var2, CString var3);
void abc(CString var1, CString var2, int var3);
void abc(CString var1, CString var2, CString var3, CString var4);
void abc(CString var1, CString var2, int var3, int var4);
void abc(CString var1, CString var2, CString var3, int var4);
void abc(CString var1, int var2, CString var3, int var4);
void abc(CString var1, CString var2, int var3, CStringvar4);
void abc(CString var1, CString var2, CString var3, CString var4, CString var5);
void abc(CString var1, CString var2, CString var3, CString var4, int var5);
void abc(CString var1, int var2, CString var3, CString var4, int var5);
void abc(CString var1, CString var2, int var3, int var4, int var5);
void abc(CString var1, CString var2, CString var3, CString var4, CString var5, CString var6 );
void abc(CString var1, CString var2, int var3, int var4, int var5, int var6);
void abc(CString var1, CString var2, CString var3, CString var4, CString var5, CString var6, CString par5);
void abc(CString var1, CString var2, CString var3, CString var4, CString var5, CString var6, int var7);
void abc(CString var1, CString var2, int var3, int var4, int var5, int var6, int var7);
void abc(CString var1, int var2, CString var3, int var4, CString var5, float var6);

var 1 ist immer vom selben Typ, deswegen definiere ich ihn gleich fest, jedoch dann geht es los und ich hab mir gedacht deswegen ein Template zu benutzen
Kann mir da jemand weiter helfen?
Du könntest höchstens die Funktionen mit der gleichen Anzahl von Parametern jeweils als Template-Funktion zusammenfassen.
Und noch ne Frage: ich habe Header und cpp-File, wo mach ich was
Templates müssen in allen abhängigen Dateien während der Kompilierung verfügbar sein damit sie ggf. instanziert werden können. D.h. man muss diese in die Headerdatei schreiben.

Gruß
 
Hi.Doch, nur so funktioniert es überhaupt.

Du könntest höchstens die Funktionen mit der gleichen Anzahl von Parametern jeweils als Template-Funktion zusammenfassen.

Templates müssen in allen abhängigen Dateien während der Kompilierung verfügbar sein damit sie ggf. instanziert werden können. D.h. man muss diese in die Headerdatei schreiben.

Gruß

Hi,
da liegt der Hund begraben,
ich sollte schauen mit einer Funktion alle anderen zu ersetzen.
Hättest du eine Idee?

Grüsse
 
Hi,
da liegt der Hund begraben,
ich sollte schauen mit einer Funktion alle anderen zu ersetzen.
Hättest du eine Idee?
Du hast 2 Möglichkeiten wenn du dies als eine Funktion umsetzen willst/musst.

Du schreibst eine Template-Funktion mit 7 Parametern (und evtl. Standardwerten).

Wenn du eine Funktion benutzen willst, mußt du entweder immer alle 7 Parameter angeben (dann kann der Compiler den Typ der Parameter bestimmen) oder du gibst die Typen beim Aufruf immer explizit an wie ich bereits demonstriert habe (dann brauchst du nicht alle Parameter angeben und kannst Defaultwerte verwenden).

Abgesehen mal von der techn. Seite, stellt sich erstmal die Frage ob es überhaupt sinnvoll ist die Funktionen so zusammenzufassen. Steht denn in jeder Funktion der gleiche Code drin?

Gruß
 
Du hast 2 Möglichkeiten wenn du dies als eine Funktion umsetzen willst/musst.

Du schreibst eine Template-Funktion mit 7 Parametern (und evtl. Standardwerten).

Wenn du eine Funktion benutzen willst, mußt du entweder immer alle 7 Parameter angeben (dann kann der Compiler den Typ der Parameter bestimmen) oder du gibst die Typen beim Aufruf immer explizit an wie ich bereits demonstriert habe (dann brauchst du nicht alle Parameter angeben und kannst Defaultwerte verwenden).

Abgesehen mal von der techn. Seite, stellt sich erstmal die Frage ob es überhaupt sinnvoll ist die Funktionen so zusammenzufassen. Steht denn in jeder Funktion der gleiche Code drin?

Gruß


Hi,
meine Funktion bekommt Werte übergeben, dich ich dann dementsprechend Auswerten muss, d.h. ich habe z.b. T0-T5 (damit habe ich die Variablen var2.... abgedeckt) als CString, int oder float und muss dann eine Ausgabe damit zusammen bauen!
ja es steht immer derselbe Code drin, nur meine Ausgaben werden dann anderst aufgebaut.

Gruss
 
Hi.
Hi,
meine Funktion bekommt Werte übergeben, dich ich dann dementsprechend Auswerten muss, d.h. ich habe z.b. T0-T5 (damit habe ich die Variablen var2.... abgedeckt) als CString, int oder float und muss dann eine Ausgabe damit zusammen bauen!
ja es steht immer derselbe Code drin, nur meine Ausgaben werden dann anderst aufgebaut.
Nun, entweder ist es der gleiche Code, oder der Code ist [bei der Ausgabe] anders.

Von deiner Beschreibung her sehe ich nicht den Sinn eine Templatefunktion zu verwenden. Zuerstmal könnte man die int und float Werte in CStrings umwandeln.

Anderenfalls könnte man auch eine Hilfsklasse verwenden und für diese eine Ausgabefunktion schreiben. Bsp:
C++:
class Param {
public:
  enum Type { t_int, t_float, t_string };

private:
  Type type;

  union {
    int i;
    float f;
  };
  string str;

  friend ostream& operator << (ostream&, const Param&);

public:
  Param(const string& s) : type(t_string), str(s) { }
  Param(int i) : type(t_int), i(i) { }
  Param(float f): type(t_float), f(f) { }
};


ostream& operator << (ostream& ostr, const Param& p) {
  switch (p.type) {
  case Param::t_int:
    return (ostr << p.i);

  case Param::t_float:
    return (ostr << p.f);

  case Param::t_string:
    return (ostr << p.str);

  default:
    throw std::logic_error("unknown type value");
  }
}

void func(Param p1, Param p2 = Param(3), Param p3 = Param("ad")) {
  cout << p1 << " " << p2 << " " << p3 << endl;
}

func(3, 5, "adsf");
func(3);
func(2, 3.4f);
Gruß
 

Neue Beiträge

Zurück