2012-05-22 16 views
10

mi sento la mia strada nel modello meta-programmazione, lentamente e non sono sicuro come implementare il seguente:C++ modello di specializzazione in base al valore di compilazione

// 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>(); 

Al momento della compilazione saprò cosa enum value il terzo tipo di template è (invariant in fase di compilazione), Dead or Alive. E 'possibile definire due corpi per la funzione di Registrazione, qualcosa di simile:

// 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 ... } 

Ho dato un'occhiata a: C++ Template Specialization with Constant Value

ma non sono stato in grado di capire come farlo si applica ai questa situazione.

risposta

11

Le funzioni dei modelli non possono essere parzialmente specializzate. La soluzione è di avvolgerla in una struttura:

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

funziona perfettamente! Grazie Pubby – Short

0

Molto tardi alla festa qui, ma.

Un modo per fare questo che penso sia concettualmente più semplice e anche più facile da leggere è semplicemente rendendo i diversi valori della vostra enum diverso tipi (all'interno di uno spazio dei nomi, per mantenerlo pulito), e sfruttare (template) overloading di funzioni:

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; 
} 

Tu li chiami così:

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