Nun möchte ich für alle möglichen T foo() für bestimmte U
spezialisieren, z.b. für U = int:
1
template<>
2
template<classT>
3
voidC<T>::foo<int>(intu){...}
Der Compiler (gcc) meldet
1
function template partial specialization 'foo<int>' is not allowed
Ich verstehe jedoch nicht ganz, warum da 'partial' steht. Ich will ja
für alle Template-Parameter von foo eine Spezialisierung machen.
Falls C selbst keine Template-Klasse ist, funktioniert das ganze.
Lässt sich mein Vorhaben irgendwie in C++ realisieren?
Grüße
- jgdo -
AFAIR kann man nur teilweise spezialisieren, wenn es sich um die gleiche
Art von Template-Parameter handelt. Wie soll das auch sonst
funktionieren? Da müsste C++ bei dir ja eventuell "nachträglich" in eine
existierende Klasse weitere überladene Funktionen einbauen. Warum machst
du nicht einfach alles als Klassenparameter?
Fabian Dreyersdorff schrieb:> Dein Problem wird durch Funktionsüberladung gelöst.
Da musst du aber für jeden Typ eine Funktion schreiben. Das will man
sich mit Templates ja sparen.
Vielen dank für eure Anregungen!
drama schrieb:> Warum machst> du nicht einfach alles als Klassenparameter?
Weil ich innerhalb der gleichen C<T>-Klasse mehrere verschiedene
foo<U>() aufrufen möchte.
Fabian Dreyersdorff schrieb:> Dein Problem wird durch Funktionsüberladung gelöst. Dafür benötigst du> keinen expliziten Templateparameter.Ralf G. schrieb:> Fabian Dreyersdorff schrieb:>> Dein Problem wird durch Funktionsüberladung gelöst.> Da musst du aber für jeden Typ eine Funktion schreiben. Das will man> sich mit Templates ja sparen.
Das könnte man tatsächlich so machen, allerdings wäre es nicht ganz
optimal. Was ich u.a. erreichen möchte, ist dass der Compiler einen
Fehler erzeugt, sobald es keine Spezialisierung von foo<U>() für einen
Typen gibt, d.h. es ist erwünscht (bzw. erforderlich), für jeden Typen
eine eigene Spezialisierung zu schreiben. Problem bei
Funkionsüberladungen wären jedoch implizite Umwandlungen. Wenn ich z.B.
nur foo(double) definiert habe, es aber mit einem int aufrufe, würde der
Compiler implizit den int nach double konvertieren und foo(double)
aufrufen. Ich will jedoch, dass in diesem Fall das Programm nicht
kompiliert, weil kein foo(int) definiert wurde.
Ich glaube das lässt sich lösen, indem man U in eine Box-Klasse packt.
Dadurch würde das implizite Casten entfallen und man könnte
Funktionsüberladungen anstatt der template-Methode nehmen.
- jgdo -
Man kann inline template funktionen, template functiuns declarationen,
überladung und default template parameter kombinieren, sollte den
gleichen effekt haben wie dass, was du versuchst zu erreichen:
jgdo schrieb:> Wenn ich z.B.> nur foo(double) definiert habe, es aber mit einem int aufrufe, würde der> Compiler implizit den int nach double konvertieren und foo(double)> aufrufen. Ich will jedoch, dass in diesem Fall das Programm nicht> kompiliert, weil kein foo(int) definiert wurde.
Hierfür könntest die Funktion ohne Funktionsrump deklarieren.
1
#include<iostream>
2
3
voidfunc(int);
4
voidfunc(doublei){
5
std::cout<<i;
6
}
7
8
intmain(void){
9
func(5);
10
return0;
11
}
Der Kompiliervorgang scheitert an einem Linkererror:
g++ undefFunc.cpp -o undefined
/tmp/ccDqcvMI.o: In function `main':
undefFunc.cpp:(.text+0x30): undefined reference to `func(int)'
collect2: error: ld returned 1 exit status
Edit:
Ralf G. schrieb:> Da musst du aber für jeden Typ eine Funktion schreiben. Das will man> sich mit Templates ja sparen.
Funktionstemplates lassen sich aber nicht spezialisieren.
Mit C++11 geht es sogar noch eleganter mit einem echten Compiler-Fehler:
1
voidfunc(doublei){
2
std::cout<<i;
3
}
4
5
template<typenameT>
6
voidfunc(T)=delete;
g++ undefFunc.cpp -std=c++11 -o undefined
undefFunc.cpp: In function ‘int main()’:
undefFunc.cpp:11:11: error: use of deleted function ‘void func(T) [with
T = int]’
func(5);
^
undefFunc.cpp:8:6: error: declared here
void func(T) = delete;
^
Fabian
jgdo schrieb:> Nun möchte ich für alle möglichen T foo() für bestimmte U> spezialisieren, z.b. für U = int:Fabian Dreyersdorff schrieb:> Funktionstemplates lassen sich aber nicht spezialisieren.
Ja, was soll hier denn 'spezialisieren' jetzt bedeuten?
a) in 'foo' über template überall den entsprechenden Typ eintragen?
(Ansonsten ist der Inhalt der Funktion überall gleich)
oder
b) für jeden Typ soll eine vollkommen andere Funktion aufgerufen werden?
(Gerne auch mit gleichem Namen) (*)
jgdo schrieb:> Falls C selbst keine Template-Klasse ist, funktioniert das ganze.
Also, irgendwas passt für mich nicht zusammen ^^
Ralf G. schrieb:> Ich hab' da möglicherweise was falsch verstanden, ...
(*) für b) würde ich noch 'pure virtual' in den Raum werfen, damit:
jgdo schrieb:> Was ich u.a. erreichen möchte, ist dass der Compiler einen> Fehler erzeugt, sobald es keine Spezialisierung von foo<U>() für einen> Typen gibt, d.h. es ist erwünscht (bzw. erforderlich), für jeden Typen> eine eigene Spezialisierung zu schreiben.
Daniel A. schrieb:> Man kann inline template funktionen, template functiuns declarationen,> überladung und default template parameter kombinieren, sollte den> gleichen effekt haben wie dass, was du versuchst zu erreichen:
Wo sind denn da default template parameter?
Wenn du eine member function in der class declaration definierst
brauchst du kein 'inline' - das ist implizit.