Wann brauche ich Template Default Argumente?
-
Hallo,
Templates (wiedermal...) - ich habe eine Verstaendnisfrage zur partieller Template Spezialisierung und der, manchmal notwendigen, Deklaration von Default Template Argumenten. Ich verwende den G++ 4.3.2.
Ich hatte vor ein paar Wochen ein Problem eine Typelist zu kompilieren. Ein Hauptproblem war, dass ich hier keine "volle" Template Klassen Definition vorangestellt hatte. Und das funktioniert auch NUR wenn ich den letzten drei (sh. Funktionsweise Typelist) Default Template Argumente verpasse, also etwa so:
... template <class T1, class T2 = null_typelist, class T3 = null_typelist, class T4 = null_typelist> struct cons ...Loesche ich nun diese Default Template Argumente in der funktionierenden Implementation weg, bekomme ich eine ganze Latte an Fehlermeldungen, beginnend mit "provided for 'template<class T1, class T2, class T3, class T4> struct cons'", dann "wrong number of template arguments", ueber "was not declared" ueber "cannot appear in a constant-expression" und es kompiliert dementsprechend nicht.
http://www.c-plusplus.net/forum/viewtopic-var-t-is-227321-and-highlight-is-typelist.html
Gut, gestern sah ich folgendes Beispiel:
http://www.iis.sinica.edu.tw/~kathy/vcstl/templates.htm#include <iostream> using namespace std ; template <class T> class stream { public: void f() { cout << "stream<T>::f()"<< endl ;} } ; template <> class stream<char> { public: void f() { cout << "stream<char>::f()"<< endl ;} } ; int main() { stream<int> si ; stream<char> sc ; si.f() ; sc.f() ; return 0 ; }Ich hab den Code gleich genommen und nachkompiliert, er kompiliert. Soweit ich das auf Dikumware/exam mit anderen Compilern ausprobiert habe kompiliert das auf allen einwandfrei. Die Frage ist: warum?
Muesste es nicht folgendermassen heissen:... template <class T = char> class stream { ...Warum kompiliert der Code ohne Beigabe eines Default Template Argumentes? Oder, warum muss ich im obigen Beispiel mit dem NULL Type default-initialisieren aber bei unterem nicht?
...oder wo ist mein Denkfehler?

-
Ich dachte du hättest es damals begriffen ... aber anscheinend nicht

Die Sache ist äusserst einfach zu verstehen, meine ich.Der richtige template Typ verlangt 4 Templateparameter bei dir. Er wird immer 4 verlangen, dass kannst du mit den Spezialisierungen nicht verhindern. Mit den Spezialisierungen kannst du nur auf spezielle angaben von Typen reagieren.
Also kurz etwas code:
Typelist<int>; // Ist nichts anderes als Typelist<int, null_typelist, null_typelist, null_typelist> // Dem entsprechend wird nun diese Spezialisierung benutzt: template<typename T1> struct Typelist<T1, null_typelist, null_typelist, null_typelist> Typelist<int, char>; // Ist nichts anderes als Typelist<int, char, null_typelist, null_typelist> // Dem entsprechend wird nun diese Spezialisierung benutzt: template<typename T1, typename T2> struct Typelist<T1, T2, null_typelist, null_typelist>Wenn die Defaultargumente nicht angeben würdest, müsstest du sie als Argumente hinschreiben:
Typelist<int, null_typelist, null_typelist, null_typelist>; Typelist<int, char, null_typelist, null_typelist>;Also das Defaultargument hat überhaupt nichts mit der Spezialiserung zu tun. Es geht nur darum, ob du alle Typen hinschreiben musst oder nicht. Ist genau gleich, wie bei den Defaultargumenten einer Funktion

Jetzt verstanden? ^^
Grüssli
-
Naja, das dachte ich auch. Aber ich bin ja auch kein Programmierer, ich tue nur so! Mein Hauptverstaendnisproblem hing wohl mit dem Policy-Problem (wieder anderer Thread) zusammen. Gut, den hast Du nun auch beantwortet. Da das Problem dort weder an "Default Template Argumenten" noch an "Template Spezialisierung" lag, sondern daran dass eine Forward Declaration bei diesen Policies nicht ausreicht (was ich immer noch seltsam finde, aber gut), ist mir das hier nun auch wieder klar.
Soweit ich das auch urspruenglich mal verstanden hatte ist das bei den Typelists die folgende Situation:
1. Zuerst Definiere ich eine Typelist mit allen Template Argumenten und setze Default Template Argumente.2. Wenn ich dann eine Typelist mit zB nur einen Template Argument verwende, werden die anderen Argumente durch die Default Template Argumente ersetzt (sh. 1.).
Soweit die "Default Template Argumente", nun kommt die "Template Spezialisierung"
3. Verwendet wird dann die jeweilige Partielle Template Spezialisierung die mit dem Default Template Typ (Null Type) in 1. und 2. erzeugt wird.
Im Beispiel hier handelt es sich lediglich um den Fall 3. und ich gebe in der Verwendung den Typ an.
D.h.
-> wenn ich weniger als die volle Anzahl der Template Argumente bei der Verwendung angeben koennen will, muss ich Default Template Argumente mitdefinieren (1. und 2. - und wie Du ebenfalls erklaert hast).-> Wenn ich unterschiedlichen Code abhaengig von den Template Argumenten verwenden will, muss ich Template Spezialisierung verwenden (3.).
Ich hoffe das passt so?! Gut danke fuer's Aufklaeren.. :xmas1: :xmas2:
-
Fabeltier schrieb:
Naja, das dachte ich auch. Aber ich bin ja auch kein Programmierer, ich tue nur so!
HOCHSTAPLER!!!

Fabeltier schrieb:
Ich hoffe das passt so?!
Wenn ich dich richtig verstanden habe, dann ja

Fabeltier schrieb:
Gut danke fuer's Aufklaeren.. :xmas1: :xmas2:
Gerngeschehen.
Grüssli