2013-04-22 3 views
13

Ciao, sto avendo problemi con la specializzazione parziale. Quello che voglio fare è avere una classe che abbia una funzione membro template che interpreti un dato valore a uno specificato dall'utente. Per esempio il nome della classe è Value ed ecco un frammento di quello che voglio fare:Ottenere "l'uso illegale di argomenti espliciti del modello" quando si esegue una specializzazione parziale del puntatore per un metodo di classe

int *ptr1 = new int; 
*ptr1 = 10; 
Value val1 = ptr1; 
int *ptr2 = val1.getValue<int*>(); 

Value val2 = 1; 
int testVal = val2.getValue<int>(); 

Ecco come ho implementato tale classe:

struct Value { 

    Value(void *p) : val1(p){} 
    Value(int i) : val2(i){} 

    template<typename T> 
    T getValue(); 

    void *val1; 
    int val2; 
}; 

template<typename T> 
T* Value::getValue<T*>() { 
    return reinterpret_cast<T*>(val1); 
} 

template<> 
int Value::getValue<int>() { 
    return val2; 
} 

Quando compilo sto ottenendo il seguente errore:

error C2768: 'Value::getValue' : illegal use of explicit template arguments

Fondamentalmente la sua lamentano la parte di modello puntatore del codice:

template<typename T> 
T* Value::getValue<T*>() { 
    return reinterpret_cast<T*>(val1); 
} 

So che questo problema può essere implementato con un semplice unione, ma questo codice è una versione ridotta di un codice più grande.

Qualcuno sa quale potrebbe essere il problema? Quello che mi piacerebbe fare è separare un codice per quando si usano puntatori e altro quando non si usano i puntatori. Sono davvero bloccato e cerco sempre di indagare, invece di chiedere, ma non ho trovato nessuna buona informazione a riguardo.

+3

I modelli di funzione non possono essere parzialmente specializzati; solo i modelli di classe possono essere. – Angew

+0

Ok si, probabilmente è così. Ricordo di averne letto in C++ Modern Design, che le funzioni non possono essere parziali. Ho pensato perché il membro funziona dove parte di una classe potresti farla franca. Non credo :(Grazie: D – Kunashu

risposta

13

I modelli di funzione non possono essere parzialmente specializzati, ma il più delle volte è possibile utilizzare il trucco delegate-class. Nel tuo esempio sarebbe come:

struct Value { 
    template<typename T> 
    T getValue() { 
    return Impl_getValue<T>::call(*this); 
    } 
}; 

template <typename T> 
struct Impl_getValue 
{ 
    static T call(Value &v) { 
    //primary template implementation 
    } 
}; 

template <typename T> 
struct Impl_getValue<T*> 
{ 
    static T* call(Value &v) { 
    return reinterpret_cast<T*>(v.val1); 
    } 
}; 
+0

Ho una domanda, il compilatore rimuoverà la chiamata extra a Impl_getValue :: call()? – Kunashu

+0

@Kunashu Se l'ottimizzatore vale qualcosa, rimuoverà tale chiamata. – Angew

Problemi correlati