template Methode in template Klasse
-
template <typename T> template<> int Matrix<T>::operator * (int & other);Muss man Spezialisierungen von template member functions in templates nicht sowieso immer in der template Klasse (also implizit inline) definieren?
Anders gesagt: AFAIK geht das garnicht, egal mit welcher Syntax
-
queer_boy schrieb:
Vorden schrieb:
template <typename T> int Matrix<T>::operator *<int> (int & other);So und noch einige andere Versuche, wie:
template <typename T> template int Matrix<T>::operator *<int> (int & other); template <typename T> template<int> int Matrix<T>::operator * (int & other);Weiß irgendwer ob das überhaupt so geht, oder bin ich gezwungen, das alles im Header zu halten (was mir persönlich nicht gefallen würde, da ich eben die Spezialisierungen ausschließlich für ein paar Datentypen hätte)
du kannst eine datei mit template-definitionen erstellen und diese am ende des headers inkludieren, dann hast du's auch getrennt.
was du suchst, nennt sich übrigens funktionsüberladung

//in der klasse: template <class T> void foo (T const& other); void foo (int other); //definition: template <class T> void X<T>::foo (int other) { //... }erm, dass ich so was wie funktionsüberladung suche, wusste ich schon, aber, wie hustbaer sagte, geht es offensichtlich nicht... ich habe das gefühl, du (queer_boy) hast nicht verstanden, um was es mir ging, scheinbar gehts leider nicht so, wie ich mir das vorgestellt hatte, ich mein, für klassen z.b. kann man ja wunderbar in der *.cpp forward-deklarationen vornehmen in der form:
template class Matrix<int>;das ist eigentlich das, was ich für funktionen gesucht habe, aber scheinbar geht es nicht so unbedingt, dann kommt des halt in den header, da gehts auch, wenn auch nicht exakt so, wie ich das wollte. schade eigentlich, aber thx. falls noch irgendwem was dazu einfällt, bitte einfach posten, ansonsten auch danke
-
erm, dass ich so was wie funktionsüberladung suche, wusste ich schon, aber, wie hustbaer sagte, geht es offensichtlich nicht...
Nönönö, Überladung != Spezialisierung.
Überladen kannst du schon:
#include <iostream> template <class T> class foo { public: // NOTE: hier drinnen heisst foo ohne template klammern automatisch immer foo<T>. template <class U> foo operator *(U u); // das template template <> foo operator *<double>(double d) // spezialisierung inline (hier geht das, ausserhalb der deklaration von foo nicht) { std::cout << "spezialisierung inline\n"; return foo(); } foo operator *(int i); // der non-template-overload }; // definition des templates template <class T> template <class U> foo<T> foo<T>::operator *(U u) { // ... std::cout << "template ausserhalb\n"; return foo<T>(); } // definition des overloads template <class T> foo<T> foo<T>::operator *(int i) { // ... std::cout << "overload ausserhalb\n"; return foo<T>(); } int main() { foo<char> f; f = f * "sepp"; // template ausserhalb f = f * 10.0; // spezialisierung inline f = f * 10; // overload ausserhalb return 0; }
-
template class Matrix<int>;Eieieiei.
DAS ist keine Spezialisierung sondern eine explizite Instanzierung.
Und DAS geht auch:// Mit "foo" aus dem letzten Beispiel: template foo<int> foo<int>::operator *<short>(short s); // explizite Instanzierung des templates
-
hustbaer schrieb:
#include <iostream> template <class T> class foo { public: // NOTE: hier drinnen heisst foo ohne template klammern automatisch immer foo<T>. template <class U> foo operator *(U u); // das template template <> foo operator *<double>(double d) // spezialisierung inline (hier geht das, ausserhalb der deklaration von foo nicht) { std::cout << "spezialisierung inline\n"; return foo(); } [...] };vielleicht sehe ich tatsächlich nicht genau, worauf der OP hinauswollte. aber wieso sollte das funktionieren? sollte das nicht eigentlich verboten sein? eine explizite spezialisierung (genauer: die deklaration einer expliziten spezialisierung, damit auch die definition) eines member templates kann doch nur im namensbereich der übergeordneten (template oder nicht)-klasse auftreten.
ich habe das gefühl, das hier etwas in der art gesucht wird, wie CStoll schon gemeint hat
CStoll schrieb:
template <typename T> template<> int Matrix<T>::operator * (int & other);
auf dein beispiel umgelegt, so etwas: (ich lasse mal zur übersichtlichkeit den code für die überladene funktion weg)
#include <iostream> template <class T> class foo { public: // NOTE: hier drinnen heisst foo ohne template klammern automatisch immer foo<T>. template <class U> foo operator *(U u); // das template //folgendes funktioniert nicht dank 14.7.3/2 /* template <> foo operator *<double>(double d) // spezialisierung inline (hier geht das, ausserhalb der deklaration von foo nicht) { std::cout << "spezialisierung inline\n"; return foo(); } */ }; //also muss man die explizitie spezialisierung außerhalb der klasse vornehmen (CStolls Idee) template <class T> template <> foo<T> foo<T>::operator * <double> (double d) { }nur leider funktioniert das auch nicht, da bei einer expliziten spezialisierung eines member-templates die sie einschließende klasse auch explizit spezialisiert werden muss. also nur so:
template <> template <> foo<int> foo<int>::operator * (int);aber ich muss zugeben, dass das nicht ganz mein spezialgebiet ist.
-
(PS: quelle) das liegt wahrscheinlich auch an der absolut und überaus einfach verständlichen regel des 14.3.7/18. wie auch immer, was man dagegen tun kann, ist eine funktionsüberladung, wie ich schon gesagt habe.
nach ein bisschen nachforschung scheinen hier verschiedene compiler-hersteller selbst keine einheitliche meinung zu haben. 14.3.7/18 spricht nur von klassentemplates, nicht aber von funktionstemplates. 14.3.7/1 würde die explizite spezialisierung auch erlauben. irgendwo ist da der hund drin...
-
das ganze mit der überladung war mir vom vornherein auch schon klar, ich wusste aber nicht, ob es eben für diese methodeproblem eine sinnvolle syntax gibt, aber scheinbar nicht. habs jetz mit überladung gelöst, z.b. wenn ich für int und double die methoden bereitstelle (is vllt nicht so schön, geht aber bislang):
//zum einen: template <typename T> class Matrix { private: //... template <typename T2> T2 operator * (T2 &other) { //... do the mul } //... public: int operator * (int &); double operator * (double &); //... };und dann in der *.cpp die Methoden definiert also für int und double, die jeweils bloß die andere mit
return operator *<int>(val);aufrufen im Endeffekt.
Is aber jetz auch noch ungetesteter code, weiß net genau, ob des funktioniert, hab leider auch grad meinen compiler hier net zur hand, macht aber, denke ich, sinn der code so
-
@queer_boy: hmpf. du hast recht. lustigerweise frisst MSVC 2005 meinen code trotzdem. comeau sudert aber richtigerweise.
irgendwie beginne ich den standard immer mehr und mehr zu hassen. so viele regeln wo ich keinen plan habe wozu sie da sind (und wie man sieht oft nichtmall DASS sie da sind *g*).
C++ is doof, ich mach ab jetzt nurmehr VB
-
queer_boy schrieb:
(PS: quelle) das liegt wahrscheinlich auch an der absolut und überaus einfach verständlichen regel des 14.3.7/18. wie auch immer, was man dagegen tun kann, ist eine funktionsüberladung, wie ich schon gesagt habe.
nach ein bisschen nachforschung scheinen hier verschiedene compiler-hersteller selbst keine einheitliche meinung zu haben. 14.3.7/18 spricht nur von klassentemplates, nicht aber von funktionstemplates. 14.3.7/1 würde die explizite spezialisierung auch erlauben. irgendwo ist da der hund drin...
Bei mir gibt es keinen Abschnitt 14.3.7
-
Er meint 14.7.3. Bei der Antwort an mich hat ers richtig geschrieben, dann hat er sich anscheinend vertan und 7 und 3 vertauscht.