2012-05-22 7 views
10

me siento a mi manera en la plantilla de meta-programación, poco a poco y no estoy seguro de cómo poner en práctica lo siguiente:C++ especialización de plantilla basada en el valor de tiempo de compilación

// hpp file 
enum MyEnum { Alive = 0, Dead }; 
class A { 
    public: 
     template<typename T, typename O, MyEnum ls> 
     static int Register(); 
}; 

// elsewhere in the code... 
A::Register<IType1, Type1, Dead>(); 

En tiempo de compilación voy a saber qué valor enum el tercer tipo de plantilla es (invariante en tiempo de compilación), Dead or Alive. ¿Es posible definir dos cuerpos de la función de Registro, algo así como:

// desired hpp file 
template<typename T, typename O, Alive> 
int Register(); 

template<typename T, typename O, Dead> 
int Register(); 

// corresponding desired .inc file 
template<typename T, typename O, Alive> 
int Register() { // Alive specific implementation ... } 

template<typename T, typename O, Dead> 
int Register() { // Dead specific implementation ... } 

He echado un vistazo a: C++ Template Specialization with Constant Value

pero no he sido capaz de averiguar cómo hacer que se aplica a las esta situación.

Respuesta

11

Las funciones de la plantilla no pueden ser parcialmente especializadas. La solución es envolverlo en una estructura:

template<typename T, typename O, MyEnum ls> 
struct foo; 

template<typename T, typename O> 
struct foo <T, O, Alive> { 
    static int Register() { 
    // ... 
    } 
}; 

template<typename T, typename O> 
struct foo <T, O, Dead> { 
    static int Register() { 
    // ... 
    } 
}; 

template<typename T, typename O, MyEnum ls> 
int Register() { 
    return foo<T, O, ls>::Register(); 
} 
+0

funciona perfecto! Gracias Pubby – Short

0

Muy tarde para la fiesta aquí, pero.

Una manera de hacer esto que creo que es conceptualmente más simple y más fácil de leer es simplemente hacer los diferentes valores de su enumeración diferente tipos (dentro de un espacio de nombres, para mantenerlo limpio), y tomar ventaja de (plantilla) sobrecarga de funciones:

namespace State { 
    struct Dead {}; 
    struct Alive {}; 
} 

template<typename T, typename O> 
int Register(State::Dead) { 
    return 1; 
} 

template<typename T, typename O> 
int Register(State::Alive) { 
    return 2; 
} 

Se les llama así:

int main() { 
    Register<int,int>(State::Dead()); 
    Register<int,int>(State::Alive()); 
    return 0; 
} 
Cuestiones relacionadas