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 declaration

    Weiss vielleicht jemand, wie das Teil richtig geht? Ich verwende Visual Studio 2008

    Mfg Samuel


  • Mod

    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 🙂


Log in to reply