2011-01-06 17 views
11

Czy można wywołać funkcję zdefiniowaną w niewyspecjalizowanej klasie szablonów z wyspecjalizowanej klasy szablonów? Oto przykład tego, co próbuję:Wywołanie niewyspecjalizowanej funkcji klasy szablonów z wyspecjalizowanej funkcji klasy szablonów

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 skarży się, że nie widzi niewyspecjalizowanej funkcji klasy; to znaczy, że wygląda tylko w obrębie specjalistycznej klasy.

Jakieś myśli?

EDIT

Oto bardziej konkretny przykład z mojego kodu (z możliwych rozwiązań):

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);  
    } 
}; 

mam inne funkcje - toString() countDigits(), itd. I wybrałem to podejście, więc mogę zachować te same nazwy funkcji dla każdego typu (tj. nie trzeba używać doStringU32(), toString32 itd.). Zastanawiałem się nad specjalizacją szablonów, ale nie sądzę, aby było to możliwe.

+1

Dlaczego starasz się wywołać niewyspecjalizowanych wersję z wyspecjalizowanej wersji funkcji? Innymi słowy, jeśli wszystko, co robisz, nazywa się wersją niewyspecjalizowaną, dlaczego potrzebujesz specjalizacji? –

+0

typ 'T' nie ma wpływu na metodę statyczną - dlaczego jest na pierwszym miejscu? To wygląda na przypadek nadużycia szablonu, dlaczego po prostu nie masz przeciążonych darmowych funkcji? – Nim

+0

Zaktualizowany post z bardziej konkretnym przykładem. – Graeme

Odpowiedz

10

Zasadniczo nie jest to możliwe.

Istnieje wiele możliwych rozwiązań, ale "oszukują". Pierwszym z nich jest przeniesienie rzeczywistej domyślnej logiki do innej funkcji, która jest wyspecjalizowana. Teraz możesz wywołać tę funkcję z obu implementacji toString.

Drugi wariant zakłada dziedziczenia z niewyspecjalizowanych klasy i zdaniu specjalnego znacznika jako argument szablonu:

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); 
} 
}; 
Powiązane problemy