2012-10-02 28 views
9

Sto provando a fare alcune cose di specializzazione parziale. Ho un tuple e voglio ripetere da un certo indice di elementi al primo indice di tupla, accumulando un valore da ciascun tipo nel tuple. Ciò sembrerebbe essere una semplice questione dell'uso di un'istanza di modello ricorsiva.Specializzazione parziale di modelli con parametri interi

Il problema è che non riesco a far funzionare la ricorsione. Per fermare la ricorsione, ho bisogno di specializzare parzialmente la funzione template alla tuple index 0. Sembra abbastanza semplice, ma non funziona.

Nota: ho rimosso la parte reale dello tuple dell'esempio, poiché non è rilevante; è la specializzazione del modello che non funziona.

template<int Index, typename Tpl> 
size_t CalcInterleaveByteOffset(const Tpl &t) 
{ 
    size_t prevOffset = CalcInterleaveByteOffset<Index - 1>(t); 
    return prevOffset + sizeof(Tpl); 
} 

template<typename Tpl> 
size_t CalcInterleaveByteOffset<0, Tpl>(const Tpl &t) 
{ 
    return 0; 
} 

GCC simply says that this kind of specialization is not allowed. È vero? C'è un altro modo per gestire questo genere di cose?

risposta

11

Di norma, per le funzioni non è consentita alcuna forma di specializzazione del modello parziale. Tuttavia è consentito per le classi. Quindi la soluzione è semplicemente spostare la funzione su un membro statico di una classe titolare di un modello.

Se è necessario dedurre gli argomenti del modello, è possibile semplicemente creare una funzione wrapper che chiama la classe basata su modello.

Il risultato è qualcosa di simile:

template<int Index, typename Tpl> 
class CalcInterleaveByteOffsetImpl 
{ 
    static size_t CalcInterleaveByteOffset(const Tpl &t) 
    { 
    // This is OK it calls the wrapper function 
    // You could also do 
    // size_t prevOffset = CalcInterleaveByteOffsetImpl<Index - 1, Tpl>::CalcInterleaveByteOffset(t); 
    size_t prevOffset = ::CalcInterleaveByteOffset<Index - 1>(t); 
    return prevOffset + sizeof(Tpl); 
    } 
}; 

template<typename Tpl> 
class CalcInterleaveByteOffsetImpl<0, Tpl> 
{ 
    static size_t CalcInterleaveByteOffset(const Tpl &t) 
    { 
    return 0; 
    } 
}; 

template<int Index, typename Tpl> 
size_t CalcInterleaveByteOffset(const Tpl &t) 
{ 
    return CalcInterlaveByteOffsetImpl<Index,Tpl>::CalcInterleaveByteOffset(t); 
} 
+0

ho potuto differenziare classe diversa con diverse variabili utenti in questo modo? Potrei indovinare si? – GameDeveloper

Problemi correlati