spez. Template
-
Hallo!
Meine Frage bezieht sich auf Funktionstemplates. Ich bin gerade am lernen wie man Templates einsetzt. Zu einem habe ich ein Buch und ein Tutorial mit folgender Adresse.
http://www.cpp-tutor.de/cpp/le15/le15_01.htm Die Aussagen sind hier die selben aber ich bekomme von meinem Compiler immer den selben Fehler bezüglich spezialisierter Templates.template <typename T> T Max(T p1, T p2) { return ((p1>p2)? p1 : p2); /*Das ist klar und funktioniert auch*/ }
/*ein anderer Code mit spezialisiertem Template*/ template<> char* Max<char*>(char* p1, char* p2) //<char*> kann man weglassen(in dem Fall (Typdeduktion)) { if (strcmp(p1,p2) > 0) return p1; else return p2; /*Hier bekomme ich eine Fehlermeldung die lautet: ... used a non template as a template ..... also soviel wie -das ich ein nicht Template als Template benutzen will*/ }
Im Buch ist es so beschrieben und wie man sieht in dem Tutorial auch, doch warum geht das nicht?
Ich verstehe es nicht, ich suche in mehreren Quellen aber ich verstehe nicht warum es nicht geht.
Im Forum habe ich auch schon gesucht, und da werden die spez. Templates auch so beschrieben. Also kann es ja nicht an einer falschen Syntax liegen!
Wenn es am Compiler liegt wäre es natürlich ein HammerDanke für jede Hilfe.
MfGPS: Kdevelop 3.1.2 (Linux) GCC 3.3.4
DevCpp aktuell mit MinGW (Windows) GCC 3.2.3
-
hast du auch beide snippets in einer datei stehen?
-
Nein! Es gibt keine Namenskonflikte.
Die wurden ausgetauscht, einmal das erste beim zweiten Mal das zweite.
Hab es einfach nach Tutorial ausprobiert, wie gesagt im Buch steht was ähnliches.
Im Internet finde ich auch die selben Informationen.MfG
-
Bei sowas spezialisiert man nicht, sondern überladet.
-
Es geht bei dem Beispiel nicht um Sinn oder Unsinn sondern das man lernt wie spez. Templates schreibt. Und in dem Tut war halt das gezeigte Beispiel.
Die Frage war -> warum man eine Fehlermeldung bekommt obwohl der Syntax ja anscheinen richtig zu sein scheint.
-
sureal schrieb:
warum man eine Fehlermeldung bekommt obwohl der Syntax ja anscheinen richtig zu sein scheint.
Syntax ist richtig.
Es sei denn, Max<char*> kennt Max<T> nicht. Dann ist es natürlich falsch.
Aber denke daran: sowas macht man höchstens zum üben, aber nicht, wenn man es ernst meinst. Weil dann ist überladung einfach besser.
-
Shade_of_Mine schrieb:
Es sei denn, Max<char*> kennt Max<T> nicht. Dann ist es natürlich falsch.
Jetzt kapier ich das endlich auch mal
Man muss ein Template anlegen und dann kann man eins spezialisieren!
Ich hatte vorher nur eins angelegt, und zwar NUR das spezialisierte. Doch jetzt begreif ich auch warum das nicht geklappt hat. Der Satz von dir hat mich zum Nachdenken gebracht.
Man sollte jemandem der keine Ahnung hat sowas auch mal erklären. Damit meine ich die Buchschreiber (nicht das Forum)! Für jemanden der sich auskennt ist das trivial, für einen Anfänger nicht.Wie und wann man die anwendet muß ich ja auch noch lernen. Vorteil soll wohl sein das keine automatische Typumwandlung angewendet wird wie es bei überladenen Funktionen der Fall ist. Macht natürlich auch Sinn.
Ob ich sowas noch mal brauche ist eine andere Sache, aber jetzt kenn ich die Grundzüge.Mfg und Danke an alle.
@esskar
Ich war zu dumm zu erkennen was du gemeint hast. War natürlich richtig.
-
sureal schrieb:
Man sollte jemandem der keine Ahnung hat sowas auch mal erklären. Damit meine ich die Buchschreiber (nicht das Forum)! Für jemanden der sich auskennt ist das trivial, für einen Anfänger nicht.
Ja, sowas ist immer ein Problem. Viele Sachen werden nicht erklärt und in einem Forum hat ja niemand eine Ahnung wie weit du bist
Wie und wann man die anwendet muß ich ja auch noch lernen. Vorteil soll wohl sein das keine automatische Typumwandlung angewendet wird wie es bei überladenen Funktionen der Fall ist. Macht natürlich auch Sinn.
Naja, aber bedenke:
(oder besser ignoriere es, sonst verwirre ich dich nur)template<typename T> void f(T t){} //1 template<typename T> void f(T* p){} //2 template<> void f(char* p){} //3 char* p; f(p);
Was wird aufgerufen?
Lustigerweise (2) und nicht (3)Sowas kann ein teuflischer Bug sein. Deshalb: wenn man Überladen kann, dann sollte man überladen - vorallem bei Funktionen (wo man ja nicht partiell spezialisieren kann) sollte man idR Überladung verwenden. Ich habe zB noch nie eine Funktion Spezialisieren müssen (was natürlich nicht heisst, dass man es um jeden Preis meiden sollte, sondern eben Überladung den vorzug geben sollte, sofern es möglich ist).
So, und das vergiss schnell wieder, sonst hast du Knoten im Gehirn
-
template spezialisierung von funktionen ist nur da nötig, wo man die template parameter angeben muss
also in so einem Fall
template<class T> T foo(){...}
-
sureal schrieb:
@esskar
Ich war zu dumm zu erkennen was du gemeint hast. War natürlich richtig.ich denke, dass hat nix mit Dummheit zu tun; Unwissenheit passt da eher.
Das macht aber nix!!!
-
Shade_of_Mine schrieb:
Was wird aufgerufen?
Lustigerweise (2) und nicht (3)Also das musste ich probieren, muß dir aber widersprechen. Gerade probiert mit DevCpp 4.9.9.1
#include <cstdlib> #include <iostream> using namespace std; template<typename T> void f(T t){cout << "das sowieso nicht" << endl;} //1 template<typename T> void f(T* p){cout << "2" << endl;} //2 template<> void f(char* p){cout << "3" << endl;} //3 int main(int argc, char *argv[]) { char* p; f(p); system("PAUSE"); return EXIT_SUCCESS; }
Die Ausgabe ist bei mir eindeutig 3
Zum Glück, sonst müsste ich leider meinen Rechner aus dem Fenster schmeissen :xmas2: