[solved] template spezialisierung funktioniert nicht
-
asoooh! das wusst' ich nicht, danke...
camper schrieb:
musst du sie allerdings trotzdem im Header deklarieren
hm. wie schreibt ma das syntaktisch an? oO
-
iko79 schrieb:
asoooh! das wusst' ich nicht, danke...
camper schrieb:
musst du sie allerdings trotzdem im Header deklarieren
hm. wie schreibt ma das syntaktisch an? oO
Wie jede andere Funktionsdeklaration. Du lässt einfach den Funktionsrumpf weg, und schreibst ein Semikolon dafür

template<> void LogClient::Log<std::stringstream>( std::stringstream &ss, LOGLEVEL logLevel );
-
so gehts, ausserhalb der klasse, hast recht.
...hätte das nämlich innerhalb der klasse versucht:class LogClient { //... template<class T> void Log( T &t, LOGLEVEL logLevel ); template<> void Log<std::stringstream>( std::stringstream &ss, LOGLEVEL logLevel ); };und dann in der cpp implementiert:
template<> void LogClient::Log<std::stringstream>( std::stringstream &ss, LOGLEVEL logLevel ) { this->Log( ss.str(), logLevel ); }hast vielleicht da auch noch schnell a idee was daran falsch ist?
-
okay, scheinbar nicht...
danke trotzdem, hast mir sehr geholfen!
-
Was bekommst du denn für einen Fehler?
Ansich sollte das schon gehen...Das "LogClient::" in der Definition von LogClient selbst ist allerdings unnötig und AFAIK auch falsch... der MSVC frisst das nur "trotzdem" (auch mit ausgeschalteten Extensions!?!).
-
... sorry falscher thread

-
*edit*
okay, ich bin ein blödmann. was hier vorhin gestanden is ging nicht weil ich ein using namespace vergessen hab. ma muss ma aber zu gute halten: die fehlermeldungen vom compiler waren ja auch net ganz aufschlussreich...

jedoch hab i jetzt ein ganz anderes problem: i möcht eine template-klasse schreiben, von der der konstruktor und eine methode spezialisiert sind. diese spezialisierungen müssen in cpps ausgelagert werden, weils sonst linker-errors hagelt. soweit noch klar. weiters müssen die spezialisierungen im headerfile deklariert werden. auch logisch. nur gehts irgendwie nicht, jedenfalls krieg ichs nicht hin, die schreibweise hunzt. hab jetzt mehrere durchprobiert:
path.h
#ifndef __PATH_H__ #define __PATH_H__ #include <ogrequaternion.h> namespace psi { template <class T> class Path { public: virtual ~Path() {} virtual T Calc( float progress ) = 0; }; template <class T> class LinearPath : public Path<T> { private: T t0; T t1; public: LinearPath( T start, T end ) : t0( start ), t1( end - start ) {} T Calc( float progress ); template <> LinearPath( Ogre::Quaternion start, Ogre::Quaternion end ); template <> Ogre::Quaternion Calc( float progress ); }; template <class T> T LinearPath<T>::Calc( float progress ) { return ( this->t0 + this->t1 * progress ); } } #endifpath.cpp
#include "Path.h" using namespace psi; template <> LinearPath<Ogre::Quaternion>::LinearPath( Ogre::Quaternion start, Ogre::Quaternion end ) : t0( start ), t1( end ) {} template <> Ogre::Quaternion LinearPath<Ogre::Quaternion>::Calc( float progress ) { return Ogre::Quaternion::Slerp( progress, this->t0, this->t1, true ); }wenn ich path.h in zwei files includiere krieg ich nen linker error.
Error 1 error LNK2005: "public: virtual class Ogre::Quaternion __thiscall psi::LinearPath<class Ogre::Quaternion>::Calc(float)" (?Calc@?$LinearPath@VQuaternion@Ogre@@@psi@@UAE?AVQuaternion@Ogre@@M@Z) already defined in mainTest.obj Path.obj
kann ma wer sagen wie die syntax ausschauen muss dass sowas klappt?
-
Deklarier die Funktion als 'inline', das sollte funktionieren.
-
Das ist aber trotzdem noch nicht korrekt.
Der 2. Konstruktor ist eine normale Überladung:
LinearPath( Ogre::Quaternion start, Ogre::Quaternion end );Und du kannst keine 2 gleichen Funktionen mit unterschiedlichen Rückgabewerten deklarieren:
T Calc( float progress ); Ogre::Quaternion Calc( float progress );Welche soll er dann bei "t.Calc(0.0f)" aufrufen?
-
danke für die antworten. i hab jetzt inzwischen nach endlosem herumprobieren hinbekommen indem ich die gesamte klasse spezialisiert hab. habs anders nicht hinbekommen. i schreib das hier nur rein, damit ich - wenn ich 's nächste mal das selbe problem hab (und das passiert bestimmt) - die lösung find.
template <class T> class LinearPath : public Path<T> { private: T t0; T t1; public: LinearPath() { this->t0 = 0; this->t1 = 0; } LinearPath( T start, T end ) { this->Set( start, end ); } T Calc( float progress ); void Set( T start, T end ) { this->t0 = start; this->t1 = end - start; } T GetStart() { return ( this->t0 ); } T GetEnd() { return ( this->t0 + this->t1 ); } }; template <class T> T LinearPath<T>::Calc( float progress ) { return ( this->t0 + this->t1 * progress ); } template <> class LinearPath<Ogre::Quaternion> : public Path<Ogre::Quaternion> { private: Ogre::Quaternion t0; Ogre::Quaternion t1; public: LinearPath( Ogre::Quaternion start, Ogre::Quaternion end ) { this->Set( start, end ); } Ogre::Quaternion Calc( float progress ); void Set( Ogre::Quaternion start, Ogre::Quaternion end ) { this->t0 = start; this->t1 = end; } Ogre::Quaternion GetStart() { return this->t0; } Ogre::Quaternion GetEnd() { return this->t1; } };#include "Path.h" using namespace psi; Ogre::Quaternion LinearPath<Ogre::Quaternion>::Calc( float progress ) { return Ogre::Quaternion::Slerp( progress, this->t0, this->t1, true ); }Th schrieb:
Welche soll er dann bei "t.Calc(0.0f)" aufrufen?
das is ja ka überladung sondern a spezialisierung. er soll natürlich die methode verwenden, die für die aktuell verwendete klasse kompiliert worden ist -> also in dem fall
LinearPath<Ogre::Quaternion> path( q1, q2 ); q = path.Calc( 0.75f );eben die spezialisierte, in dem fall
LinearPath<int> path( 10, 120 ); i = path.Calc( 0.75f );eine für int kompilierte version.