Partielle Spezialisierung einer Templateklassen Methode
-
Hallo zusammen
Ich möchte eine einzelne Methode eines Klassentemplates partiell spezialisieren (nicht überladen). Ist dies in C++ mögliche und wenn ja wie?Mit überladen habe ich es auch versucht:
template<class TK,class TI> bool RedBlackTree<TK,TI>::KeyExists(string *Key) const;und erhalte folgenden Fehler:
1>c:\users\samuel\desktop\projekte\serenity\serenity\development\serenity\resourceservice.cpp(1072) : error C2668: 'Dictionary<TK,TI>::KeyExists' : ambiguous call to overloaded function
1> with
1> [
1> TK=string *,
1> TI=Resource *
1> ]
1> c:\users\samuel\desktop\projekte\serenity\serenity\development\serenity\datastructures.h(1030): could be 'bool Dictionary<TK,TI>::KeyExists(string
const'
1> with
1> [
1> TK=string *,
1> TI=Resource *
1> ]
1> c:\users\samuel\desktop\projekte\serenity\serenity\development\serenity\datastructures.h(1029): or 'bool Dictionary<TK,TI>::KeyExists(const TK &) const'
1> with
1> [
1> TK=string *,
1> TI=Resource *
1> ]
1> while trying to match the argument list '(string *)'Mein Versuch einer partiellen Spezialisierung ist leider auch kläglich gescheitert:
template<string*,class TI> bool RedBlackTree<string*,TI>::KeyExists(string *Key) const;1>c:\users\samuel\desktop\projekte\serenity\serenity\development\serenity\redblacktree.cpp(5038) : error C3860: template argument list following class template name must list parameters in the order used in template parameter list
1>c:\users\samuel\desktop\projekte\serenity\serenity\development\serenity\redblacktree.cpp(5038) : error C3855: 'RedBlackTree<TK,TI>': template parameter 'TK' is incompatible with the declarationWeiss vielleicht jemand, wie das Teil richtig geht? Ich verwende Visual Studio 2008
Mfg Samuel
-
Funktionstemplates können nicht partiell spezialisiert werden.
-
Hmmm OK,
Wie kann ich dieses Problem lösen? Ich möchte ja natürlich nicht die ganzen Datenstrukturen noch einmal implementieren nur wegen den C-Strings...
-
Was genau hast du denn vor, wozu brauchst du eine Spezialisierung? Könnte etwas wie type traits dein Problem lösen?
-
Nun ja, die C-String Variante benötigt ein strcmp und kein < operator. Das ist mein Problem

-
Dann benutz doch ein templated Function object zum Vergleichen:
template<typename T> struct comparator { bool operator()( const T& op1, const T& op2 ) const { return op1 < op2; } }; template<> struct comparator<char*> { bool operator()( const char* op1, const char* op2 ) const { return strcmp( op1, op2 ) < 0; } };In deiner Dictionary Klasse legst du ein Objekt davon an und benutzt es zum Vergleichen:
template<typename TK, typename TI> class Dictionary { comparator<TK> compare_; ... };
-
Also die Find, KeyExists usw. benutzt den < operator für die Sortierung. Das Problem ist nun, dass dies bei einem C-String nutzlos ist, weil ich ja nicht überprüfen will, welche Startadresse kleiner ist, sondern ich benötige einen lexikalischen Vergleich (strcmp)...
Es muss doch eine Möglichkeit geben, dies zu handeln?
-
@DocShoe
Clever...
-
Ishildur schrieb:
Also die Find, KeyExists usw. benutzt den < operator für die Sortierung. Das Problem ist nun, dass dies bei einem C-String nutzlos ist, weil ich ja nicht überprüfen will, welche Startadresse kleiner ist, sondern ich benötige einen lexikalischen Vergleich (strcmp)...
Es muss doch eine Möglichkeit geben, dies zu handeln?

Ja genau das habe ich doch vorgeschlagen. Für char* wird strcmp benutzt, für alle anderen Typen operator<().
PS:
Kannst ja mal gucken, ob std::less nicht genau das ist, was du brauchst. Es könnte bereits eine Spezialisierung für C-Strings geben.PPS:
Nö, std::less kanns nicht, zumindest nicht in meiner Implementation der STL
-
Ja unsere Beiträge hatten sich überschnitten. Ich finde deinen Lösungsansatz super und bin gerade dabei, ihn zu implementieren
