2011-01-06 14 views
11

È possibile chiamare una funzione definita in una classe template non specializzata da una classe template specializzata? Ecco un esempio di ciò che sto tentando:Chiama la funzione di classe template non specializzata dalla funzione di classe template specializzata

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 lamenta che non può vedere la funzione di classe non specializzata; Immagino che riguardi solo la classe specializzata.

Qualche idea?

EDIT

Ecco un esempio più concreto dal mio codice (con una possibile soluzione):

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

ho altre funzioni - toString(), countDigits(), ecc I ho scelto questo approccio in modo da poter mantenere lo stesso nome di funzione per ogni tipo (cioè non è necessario toStringU32(), toString32, ecc.). Ho preso in considerazione la specializzazione dei modelli ma non credo sia possibile.

+1

Perché stai cercando di chiamare la versione non specializzata dalla versione specializzata della funzione? In altre parole, se tutto ciò che stai facendo è chiamare la versione non specializzata, perché hai bisogno che sia specializzata? –

+0

il tipo 'T' non ha alcun rapporto con il metodo statico - perché è lì dentro in primo luogo? Questo sembra un caso di abuso di modelli, perché non hai semplicemente sovraccaricato le funzioni libere? – Nim

+0

Post aggiornato con un esempio più concreto. – Graeme

risposta

10

In generale, questo non è possibile.

Ci sono diverse soluzioni possibili ma "imbrogliano". Il primo consiste nel rimuovere la logica predefinita effettiva in una funzione diversa che è non specializzata. Ora puoi chiamare questa funzione da entrambe le implementazioni toString.

La seconda alternativa prevede che eredita dalla classe non specializzato e il superamento di un tag speciale come argomento modello:

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