2012-05-22 1 views
10

я чувствую себя свой путь в шаблоне мета-программирование, медленно и я не уверен, как реализовать следующее:C++ шаблон специализация на основе компиляции значения времени

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

во время компиляции я знаю, что Значение enum означает, что третий тип шаблона (инвариант времени компиляции), либо Dead, либо Alive. Можно определить два тела для функции регистра, что-то вроде:

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

Я принял взглянуть на: C++ Template Specialization with Constant Value

, но я не мог понять, как сделать его применить к эта ситуация.

ответ

11

Функции шаблона не могут быть частично специализированы. Решение состоит в том, чтобы обернуть его в структуру:

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

Работает отлично! Спасибо, Pubby – Short

0

Очень поздно на вечеринку здесь, но.

способ сделать это, что я думаю, что это концептуально проще, а также легче читать просто делает различные значения вашего перечисления различного типов (внутри пространства имен, чтобы держать его в чистоте), и воспользоваться (шаблон) функция перегрузки:

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

Вы называете их, как это:

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