2011-09-26 16 views
6

Tengo una clase de plantilla con un parámetro de plantilla int y una plantilla. Ahora quiero especializar una función miembro:Cómo especializar miembro de la clase de plantilla con el parámetro de plantilla de plantilla

template <int I> class Default{}; 
template <int N = 0, template<int> class T = Default> struct Class 
{ 
    void member(); 
}; 

// member definition 
template <int N, template<int> class T> inline void Class<N, T>::member() {} 

// partial specialisation, yields compiler error 
template <template<int> class T> inline void Class<1, T>::member() {} 

Puede alguien decirme si esto es posible y lo que estoy haciendo mal en la última línea?

EDITAR: Me gustaría agradecer a todos por su contribución. Como también necesito una especialización para algunos T, opté por la solución sugerida por Nawaz y he especializado toda la clase, ya que solo tenía una función miembro y un miembro de datos de todos modos.

Respuesta

6

No puede parcialmente especializar una función de miembro único, tendrá que hacerlo para toda la clase.

template <int I> class Default{}; 
template <int N = 0, template<int> class T = Default> struct Class 
{ 
    void member(); 
}; 

// member definition 
template <int N, template<int> class T> inline void Class<N, T>::member() {} 

// partial specialization 
template <template<int> class T> struct Class<1, T> 
{ 
    void member() {} 
}; 
2

En C++ no está permitido especializar parcialmente una función; solo puedes especializar parcialmente clases y estructuras. Creo que esto también se aplica a las funciones de los miembros.

2

Comprobar este artículo Salida: http://www.gotw.ca/publications/mill17.htm

Es bastante pequeño, y tiene buenos ejemplos de código. Explicará el problema con la especialización de función de plantilla patial y mostrará otras formas de hacerlo.

3

Como esto no está permitido, aquí es una solución alternativa:

template <int I> class Default{}; 

template <int N = 0, template<int> class T = Default> 
struct Class 
{ 
    void member() 
    { 
     worker(int2type<N>()); //forward the call 
    } 
private: 
    template<int N> struct int2type {}; 

    template<int M> 
    void worker(const int2type<M>&) //function template 
    { 
     //general for all N, where N != 1 
    } 
    void worker(const int2type<1>&) //overload 
    { 
     //specialization for N == 1 
    } 
}; 

La idea es, cuando N = 1, la llamada de función worker(int2type<N>()) resolverá a la segunda función (la especialidad), porque estamos pasando una instancia del tipo int2type<1>. De lo contrario, la primera función, la general, se resolverá.

Cuestiones relacionadas