2011-01-06 10 views
11

Ist es möglich, eine in einer nicht spezialisierten Template-Klasse definierte Funktion aus einer speziellen Template-Klasse aufzurufen? Hier ist ein Beispiel dafür, was ich versuche:Aufruf nicht spezialisierte Template-Klassenfunktion von spezialisierten Template-Klassenfunktion

template <typename T> 
struct Convert 
{ 
static inline void toString(unsigned num, unsigned places, std::string& str) { ... } 
}; 

template <> 
struct Convert<int8_t> 
{ 
static inline void toString(unsigned num, std::string& str) 
{ 
    Convert<int8_t>::toString(num, digitis(num), str); 
} 
}; 

GCC beschwert sich, dass es nicht die Nicht-Fachklassenfunktion sehen können; ich denke, es sieht nur innerhalb der spezialisierten Klasse aus.

Irgendwelche Gedanken?

EDIT

Hier ist ein konkretes Beispiel aus meinem Code (mit einer möglichen Lösung):

struct NonSpecial { }; 

template <typename T> 
class Convert 
{ 

     template <typename R> 
     static inline R fromString(const register char *str, const unsigned str_len) 
     { 
      R result = 0; 
      //convert str to R 
      return result; 
     } 

     friend class Convert<int8_t>; 
     friend class Convert<uint8_t>; 
} 

template <> 
struct Convert<int8_t>  
{ 
    static inline int8_t fromString(const register char* str, const unsigned str_len = 4) 
    { 
     Convert<NonSpecial>::fromString<int8_t>(str, str_len);  
    } 
}; 

template <> 
struct Convert<uint8_t>  
{ 
    static inline uint8_t fromString(const register char* str, const unsigned str_len = 3) 
    { 
     Convert<NonSpecial>::fromString<uint8_t>(str, str_len);  
    } 
}; 

ich andere Funktionen haben - toString(), countDigits() usw. I Ich habe diesen Ansatz gewählt, damit ich für jeden Typ die gleichen Funktionsnamen behalten kann (also nicht toStringU32(), toString32, etc.). Ich habe die Template-Spezialisierung in Betracht gezogen, aber ich glaube nicht, dass dies möglich ist.

+1

Warum Sie versuchen, die nicht spezialisierte Version von der spezialisierten Version der Funktion zu nennen? Mit anderen Worten, wenn Sie nur die nicht spezialisierte Version aufrufen, warum brauchen Sie dann eine Spezialisierung? –

+0

der Typ 'T' hat keinen Einfluss auf die statische Methode - warum ist er überhaupt dort? Das sieht nach einem Template-Missbrauch aus, warum hast du nicht einfach die freien Funktionen überladen? – Nim

+0

Aktualisierter Beitrag mit konkreterem Beispiel. – Graeme

Antwort

10

Im Allgemeinen ist dies nicht möglich.

Es gibt verschiedene mögliche Lösungen, aber sie "betrügen". Die erste besteht darin, die tatsächliche Standardlogik in eine andere Funktion zu hieven, die auf nicht spezialisiert ist. Jetzt können Sie diese Funktion von beiden toString Implementierungen aufrufen.

Die zweite Alternative bringt aus der nicht-spezialisierten Klasse erbt und einen speziellen Tag als Template-Argument übergeben:

struct BaseClassTag { }; 

template <> 
struct Convert<int8_t> : public Convert<BaseClassTag> 
{ 
typedef Convert<BaseClassTag> TBase; 
static inline void toString(unsigned num, std::string& str) 
{ 
    TBase::toString(num, digitis(num), str); 
} 
}; 
Verwandte Themen