Template spezialisierung ohne template?
-
@ tachyon: eh nein nicht ganz
template<typename T> class Test { public: void foo(Test<double> t); void foo(Test<int> t); }; //Test.cpp #include "Test.h" template<> void Test<double>::foo(Test<double> t) { std::cout << "foo<double>()\n"; } template<> void Test<int>::foo(Test<int> t) { std::cout << "foo<int>()\n"; } int main() { Test<int> t1; Test<double> t2; t1.foo(); //Ausgabe: foo<int>() t2.foo(); //Ausgabe: foo<double>() }Was sind default template-argumente und wie benutzt man diese?
-
was so nicht geht in der main einfach myClass.foo() zu machen.
natürlich geht das.
bloss dass du wohl nicht 1:1 deinen code hier gepostet hast.hat aber kaum jemand hier lust zu raten.
vermutlich hast du ein funktions-template, und nicht wie hier beschrieben ein klassen-template.
-
selbstverständlich habe ich nicht 1:1 code gepostet. Soll ihc jetzt 10000 LOCs posten oder wie?
Ich habe ein Klassentemplate und in dieser klasse soll es aber eine funktion zur ausgabe geben. Da aber die ausgabe template-typ abhängig ist habe ich template-spezialisierungen benutzt. Nur kann ich ja nicht ein
template<> void Test<double>::print_data() ohne template typ verwenden
oder doch?
-
Mati schrieb:
...Nur kann ich ja nicht ein
template<> void Test<double>::print_data() ohne template typ verwenden
oder doch?Nur mal zum Verständnis: Du hast ein allgemeines Template (nicht spezialisiert). Und nur die Methode zur Ausgabe soll spezialisiert sein. Der Rest soll weiterhin generisch bleiben. Verstehe ich das richtig?
-
Nur mal zum Verständnis: Du hast ein allgemeines Template (nicht spezialisiert). Und nur die Methode zur Ausgabe soll spezialisiert sein. Der Rest soll weiterhin generisch bleiben. Verstehe ich das richtig?
Ja richtig.
-
Warum machst Du dann kein Function Template?
(Oder wenn die Impl. vom Argument Typ anhängig ist eine Überadung..)Simon
-
Warum machst Du dann kein Function Template?
(Oder wenn die Impl. vom Argument Typ anhängig ist eine Überadung..)nichts für ungut und danke für die Hilfe aber genau deswegen habe ich gepostet...ich weiß eben nicht wie ich es machen soll und mir fehlt auch ein beispiel damit ich es verstehe...
-
Er.
Also nochmal langsam.
Was du schreibst (die Variante die angeblich nicht geht), GEHT.
Abgesehen davon dass du bei der Spezialisierung den Return-Typ vergessen hast, was natürlich dann kein Compiler mehr fressen wird.Ganz konkret, dieser Code funktioniert wie erwartet:
#include <iostream> template <class T> class foo { public: void aaa() { std::cout << "aaa (generic)\n"; } void test(); }; // foo::test spezialisierung für foo<double> template <> void foo<double>::test() // du hast das "void" hier vergessen, was ja wohl nicht gehen kann { std::cout << "test (double)\n"; aaa(); } // foo::test spezialisierung für foo<int> template <> void foo<int>::test() { std::cout << "test (int)\n"; aaa(); } int main(int argc, char** argv) { foo<double> fd; foo<int> fi; fd.test(); fi.test(); return 0; }output ist
test (double) aaa (generic) test (int) aaa (generic)selbstverständlich habe ich nicht 1:1 code gepostet. Soll ihc jetzt 10000 LOCs posten oder wie?
Nein. Du sollst ein Minimal-Beispiel machen, compilieren, und dann inklusive der Compiler- bzw. Linker-Fehlermeldungen posten. Oder, falls es compiliert & linkt, aber das falsche Ergebnis liefert: das erwartete Ergebnis sowie das beobachtete Ergebnis posten (idealerweise Output eines Konsolenprogramms, wie das von mir gezeigte Beispiel).
Und zwar 1:1 den Code des Minimal-Beispiels posten, und nicht mal eben irgendwas in den Browser reinhacken, wobei du dann 10 andere Fehler machst.(Es ist immer ganz toll, wenn man jmd. auf einen Fehler in seinem Code aufmerksam macht, und der dann antwortet "ja blah, das is ja nur hir in forum faltsch, in mein toller programm is DAS eh richtick, muss also liegt an wahs anderen, harhar")
Genau das (1:1 Code + Fehlermeldung posten) hast du nicht gemacht. Hättest du es gemacht, hättest du vermutlich auch viel schneller eine hilfreiche Antwort erhalten.
Verstehst du jetzt worauf ich hinaus wollte?
-
Danke für die ausführliche antwort. Ich habe alles verstanden und versuche in zukunft minimalbeispiele aufzusetzen.
Weitere Frage:
Wenn ich eine Methode in einer Template-basierten KLasse habe die ich aufrufen möchte noch bevor ich weiß welche template-typen die klasse haben wird - dann bin ich doch gezwungen einfach dummy-typen zu nehmen oder?Also ich möchte sowas schaffen:
#include <iostream> template <class T> class foo { public: void bar() }; template <class T> void foo<T>::bar() { std::cout << "bar()"; } int main(int argc, char** argv) { foo<double> fd; fd.bar(); return 0; }
-
Mati schrieb:
Weitere Frage:
Wenn ich eine Methode in einer Template-basierten KLasse habe die ich aufrufen möchte noch bevor ich weiß welche template-typen die klasse haben wird - dann bin ich doch gezwungen einfach dummy-typen zu nehmen oder?Verstehe ich nicht. Kannst du mal ein Beispiel geben? Eigentlich sollte man nie dummy-Typen nötig haben.
Also ich möchte sowas schaffen:
[...]Und? Funktioniert doch schon so. Gibt bar() aus.
-
Hmm - ich habe mein design umgestellt und so geht es. Folgende Frage beschäftigt mich aber: Kann ich eine Templatespezialisierung aus einer templatebasierten klasse aufrufen?
Also sowas:
#include <iostream> template <class T> class foo { public: void bar(); void myfunction(int var); void myfunction(double var); }; template <class T> void foo<T>::bar() { int var = 9; std::cout << "bar()"; myfunction(var); }// die foo.cpp #include "foo.h" template<> void foo<int>::myfunction(int a) { std::cout << "myfunction int"; } template<> void foo<double>::myfunction(double a) { std::cout << "myfunction double"; }und die main.cpp
#include "foo.h" // die main int main(int argc, char** argv) { foo<double> fd; fd.bar(); return 0; }Der Fehler der ensteht ist folgender:
warning: no newline at end of file main.cpp:16:2: warning: no newline at end of file /tmp/ccS0tURA.o: In function `foo<double>::bar()': main.cpp:(.text._ZN3fooIdE3barEv[foo<double>::bar()]+0x2f): undefined reference to `foo<double>::myfunction(int)' collect2: ld gab 1 als Ende-Status zurückGeht das nicht?
-
Naja. Steht ja in der Fehlermeldung.
Die Funktion mit der Signatur:
void foo<double>::myfunction(double a)wird nicht instanziert. Du hast ja lediglich
void foo<int>::myfunction(int a)Da du aber foo<double> hast geht das nicht.
-
bin ihc jetzt blöd? Ich seh meinen fehler nicht.
Geht das nicht weil ichs falsch hab oder gehts allgemein nicht?aber auch so gehts nicht:
// die foo.cpp #include "foo.h" template<> void foo<int>::myfunction(int& a) { std::cout << "myfunction int"; } template<> void foo<double>::myfunction(double& a) { std::cout << "myfunction double"; }#include <iostream> template <class T> class foo { public: void bar(); void myfunction(int& a); void myfunction(double& a); }; template <class T> void foo<T>::bar() { T var; std::cout << "bar()"; myfunction(var); }
-
Für
foo<double>hatmyfunction(int)lediglich eine Deklaration jedoch keine Definition. Du versuchst aber infoo<double>::bar()foo<double>::myfunction(int)aufzurufen. Da fehlt jedoch der Rumpf...
-
genau das will ich ja erreichen- geht sowas nicht? Muss ich da für jeden T-typen eine leere template-spezialisierungs funktion anlegen?Doch wie kann ich innerhalb eine template-funktion abhängig vom Template-Typen in Template-spezialisierungen unterschiedlicher signatur springen? Muss ich wirklich für alle typen identische signatur-templates zur verfügung stellen die dann leer sind? so dummy template-spezialisierungen?
-
template <class T> class foo { public: void bar(); void myfunction(T& a); };