2011-01-06 17 views
11

¿Es posible llamar a una función definida en una clase de plantilla no especializada desde una clase de plantilla especializada? Aquí está un ejemplo de lo que estoy tratando:Llamar a la función de clase de plantilla no especializada desde la función de clase de plantilla especializada

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 se queja de que no puede ver la función de clase no especializado; es decir, supongo que solo se ve dentro de la clase especializada.

¿Alguna idea?

EDITAR

Aquí está un ejemplo más concreto de mi código (con una posible solución):

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

tengo otras funciones - toString(), countDigits(), etc. he elegido este enfoque para poder mantener los mismos nombres de funciones para cada tipo (es decir, no necesito toStringU32(), toString32, etc.). Consideré la especialización de plantillas, pero no creo que esto sea posible.

+1

Por qué estás tratando de llamar a la versión no especializado de la versión especializada de la función? En otras palabras, si todo lo que está haciendo es llamar a la versión no especializada, ¿por qué necesita que sea especializada? –

+0

el tipo 'T' no tiene relación con el método estático. ¿Por qué está allí en primer lugar? Esto parece un caso de abuso de plantilla, ¿por qué simplemente no tiene funciones gratuitas sobrecargadas? – Nim

+0

Publicación actualizada con un ejemplo más concreto. – Graeme

Respuesta

10

En general, esto no es posible.

Existen diferentes soluciones posibles, pero "engañan". La primera es elevar la lógica predeterminada real a una función diferente que es no especializada. Ahora puede llamar a esta función desde ambas implementaciones toString.

La segunda alternativa implica que hereda de la clase no especializado y pasando una etiqueta especial como el argumento de plantilla:

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