2012-05-22 10 views
10

czuję moją drogę do szablonu meta-programowania, powoli i nie jestem pewien, jak wdrożyć następujące:C++ specjalizacja szablonu na podstawie kompilacji wartości czasu

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

w czasie kompilacji będzie wiem co wartość wyliczeniowa trzeci typ szablonu to (niezmienna w czasie kompilacji), martwa lub żywa. Czy jest możliwe aby zdefiniować dwa ciała dla funkcji rejestru, coś jak:

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

Brałem spojrzeć na: C++ Template Specialization with Constant Value

ale nie byłem w stanie dowiedzieć się, jak zrobić to dotyczy ta sytuacja.

Odpowiedz

11

Funkcje szablonów nie mogą być częściowo wyspecjalizowane. Rozwiązaniem jest zawinięcie go w strukturę:

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

Works perfect! Dziękuję Pubby – Short

0

Bardzo późno na przyjęcie tutaj, ale.

Sposobem na to, że myślę zrobić jest koncepcyjnie prostsze i łatwiejsze do odczytania jest po prostu co różne wartości swojej wyliczenia innego rodzaje (wewnątrz przestrzeni nazw, aby utrzymać go w czystości), a także skorzystać z (szablon) funkcja przeciążenia:

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

je nazwać tak:

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