2012-01-31 5 views
15

puede alguien explicar por qué el compilador sólo acepta el códigoplantilla sobrecarga y SFINAE trabajar sólo con las funciones pero no clases

template<typename L, size_t offset, typename enable_if< (offset<sizeof(L)), int >::type =0> 
void a_function(){} 

template<typename L, size_t offset, typename enable_if< (offset==sizeof(L)), int >::type =0> 
void a_function(){} 

pero no esto:

template<typename L, size_t offset, typename enable_if< (offset<sizeof(L)), int >::type =0> 
class a_class{}; 

template<typename L, size_t offset, typename enable_if< (offset==sizeof(L)), int >::type =0> 
class a_class{}; 

El compilador ve la segunda plantilla de clase como una redefinición de la primera.

+2

Oh que '<' 'antes sizeof' hace que mi dolor cerebral^_ ^' –

Respuesta

12

Tienes que utilizar la especialización para las clases. Por lo general, se realiza con un parámetro adicional:

template <class P, class dummy = void> 
class T; 

template <class P> 
class T<P, typename enable_if<something, void>::type> { 
    the real thing 
}; 

dos clases (o plantilla de clase) declaraciones con el mismo nombre siempre debe declarar la misma clase o plantilla de clase (o sea una especialización, en cuyo caso es todavía la misma plantilla).

+0

typename enable_if :: type = 0' es equivalente a 'int __anonymous_param = 0' cuando' something' es verdadero. – kennytm

+0

¿Pero por qué tuvo éxito para las funciones? –

+2

@LightnessRacesinOrbit porque puede sobrecargar funciones, pero no tipos. En la versión de función está definiendo dos posibles sobrecargas (para diferentes conjuntos de tipos), mientras que en el segundo caso está definiendo dos plantillas con el mismo nombre que no se pueden hacer. Dos funciones con un nombre correcto (siempre que no sean ambiguas), dos tipos con el mismo nombre, no tan finas, incluso si son realmente plantillas de tipo. –

1

es probable que desee hacer algo como esto (ideone.com link):

#include <iostream> 

template< typename PL, size_t pOffset, int pC = int(sizeof(PL)) - int(pOffset) >= 0 ? (int(sizeof(PL)) - int(pOffset) == 0 ? 0 : 1) : -1 > 
class TClass 
{ 
}; 

template< typename PL, size_t pOffset > 
class TClass< PL, pOffset, -1 > 
{ 
public: 
    static int const sI = -1; 
}; 

template< typename PL, size_t pOffset > 
class TClass< PL, pOffset, 0 > 
{ 
public: 
    static int const sI = 0; 
}; 

template< typename PL, size_t pOffset > 
class TClass< PL, pOffset, 1 > 
{ 
public: 
    static int const sI = 1; 
}; 

int main(void) 
{ 
TClass< char, 0 > lC0; 
TClass< char, 1 > lC1; 
TClass< char, 2 > lC2; 

std::cout << lC0.sI << " : " << lC1.sI << " : " << lC2.sI << std::endl; 

return (0); 
} 

La salida del programa:

1 : 0 : -1 
Cuestiones relacionadas