2012-10-02 19 views
9

Estoy tratando de hacer algunas cosas de especialización parcial. Tengo un tuple y quiero iterar desde un determinado índice de elemento hasta el primer índice de tupla, acumulando un valor de cada tipo en el tuple. Esto parece ser una simple cuestión de usar una instanciación de plantilla recursiva.Especialización parcial de plantillas con parámetros enteros

El problema es que parece que la recursividad no funciona. Para detener la recursión, necesito especializar parcialmente la función de plantilla en el índice de tupla 0. Parecía bastante simple, pero no funciona.

Nota: He eliminado las cosas reales tuple del ejemplo, ya que es irrelevante; es la especialización de plantillas que no funciona.

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. ¿Es eso cierto? ¿Hay alguna otra forma de manejar este tipo de cosas?

Respuesta

11

Como regla general, no se permite ninguna forma de especialización de plantilla parcial para las funciones. Sin embargo, está permitido para las clases. Entonces, la solución es simplemente mover su función a un miembro estático de una clase de titular con plantilla.

Si necesita deducir los argumentos de la plantilla, puede simplemente crear una función contenedora que llame a la clase de plantilla.

El resultado es algo como esto:

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

podía diferenciar clase diferente con diferentes variables de los miembros de esta manera? ¿Podría adivinar que sí? – GameDeveloper

Cuestiones relacionadas