Klassentemplate spezialisierungsproblem
-
Hi,
ich habe ein problem mit einem klassentemplate und der spezialisierung eines funktionstemplates darin.
Hier mal der Fall:
//Klassentemplate template< class POSITIONTYPE, class POSITIONDATATYPE, class DATATYPE > class PTG { //[...] protected: void Compute(const int cpu = 0); //[...] }; //Standard implementierung template< class POSITIONTYPE, class POSITIONDATATYPE, class DATATYPE > void PTG<POSITIONTYPE,POSITIONDATATYPE,DATATYPE>::Compute(const int cpu) { //[...] } //Spezialisierung template< > void PTG< std::vector < vector3f >, vector3f, double >::Compute(const int cpu) { //[...] }Kompilieren tut es bis zum Build selber, dann erhalte ich einen Link error 2005. Die Funktion PTG< std::vector < vector3f >, vector3f, double >Compute() sei mehrmals definiert (also bereits in cptg.obj definiert). Nun, nehme ich die Spezialisierung heraus geht alles wunderbar, also scheint meine implementation irgendwie falsch zu sein. Steh ich aufm schlauch oder woran liegt das? Habe ich was falsch gemacht oder vergessen?
Vielen Dank bereits
-
Du spezialisierst da eine Funktion, und nicht die Klasse. So bekommst Du einmal
Computedurch das Template, und einmal durch die "Spezialisierung". Beide haben aber die gleiche Signatur. Ergo: doppelte Definition. -> geht so nicht.
Mach ggf. eine Template-Funktion ausCompute.
-
Hi,
Tachyon schrieb:
Du spezialisierst da eine Funktion, und nicht die Klasse.
Ich will ja auch gar nicht die Klasse spezialisieren, ich spezialisiere die memberfunktion der Klasse was nichts anderes als ein Funktionstemplate sein dürfte. Oder was meinst du?
So bekommst Du einmal
Computedurch das Template, und einmal durch die "Spezialisierung".
Beide haben aber die gleiche Signatur. Ergo: doppelte Definition. -> geht so nicht. Mach ggf. eine Template-Funktion ausCompute.Du sagst also dass eine Memberfunktion einer Templateklasse nicht direkt spezialisiert werden kann? Oder bedarf es eine templateparameters in der Signatur damit dies möglich ist?
Danke
-
Eigentlich sollte das funktionieren. Hast du die spezialisierte Funktion möglicherweise wirklich mehrmals definiert, weil du sie vielleicht (aus Gewohnheit von unspezialisierten Templates) in einen Header geschrieben hast? Dann wäre sie nämlich in mehreren Übersetzungseinheiten vorhanden, was den Fehler verursachen könnte.
-
SeppJ schrieb:
Eigentlich sollte das funktionieren. Hast du die spezialisierte Funktion möglicherweise wirklich mehrmals definiert, weil du sie vielleicht (aus Gewohnheit von unspezialisierten Templates) in einen Header geschrieben hast? Dann wäre sie nämlich in mehreren Übersetzungseinheiten vorhanden, was den Fehler verursachen könnte.
*auf die stirn klatsch* Ja natürlich! Vielen Dank, daran hatte ich tatsächlich überhaupt nicht gedacht. Ich erinnere mich jetzt auch dass ich genau den gleichen Fehler schonmal vor ein paar Wochen gemacht hatte. Man, und nichts daraus gelernt.
Danke jetzt geht alles wunderbar!
-
Hmm, ok, doch noch ein Problem. Also die spezialisierung in die implementationsdatei gepackt und die linker errors sind weg, aber leider sieht der compiler nun die spezialisierung nicht mehr.

Wenn ich ein entsprechendes Objekt der Klasse erzeuge scheint es dass er versucht die templateklasse heranzuziehen bei Compute memberaufruf anstatt der spezialisierung (und ich erhalte natürlich kompilierungsfehler deswegen weil die funktion für einen std::vector z.b. keinen sinn macht. Logisch, deswegen ja die spezialisierung nich). Hast du eine Idee wo der Fehler liegen könnte?
-
Hast du die Spezialisierung im Header deklariert?
-
SeppJ schrieb:
Hast du die Spezialisierung im Header deklariert?
Ich muss weg...Danke!
-
Eine Spezialisierung eines Funktionstemplates ist eine Funktion und darf gemäß ODR demzufolge innerhalb eines Programmes nur einmal definiert werden, es sei denn, es handelt sich um eine inline-Funktion. In diesem Zusammenhang ist zu bedenken, das auch eine implizite Instantiierung einer Templatespezialisierung einer Definition gleichsteht. Deshalb muss die Spezialisierung, die gesondert definiert wird in jeder Übersetzungseinheit, in der sie (auf eine Weise, die eine Instantiierung zur Folge hätte) verwendet wird, deklariert werden.