Специализация шаблона С++, основанная на значении времени компиляции
Я медленно вписываюсь в мета-программирование шаблонов, и я не уверен, как реализовать следующее:
// 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. Можно ли определить два тела для функции Register, например:
// 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 ... }
Я посмотрел: Специализация по шаблону С++ с постоянным значением
но я не смог выяснить, как это применимо к этой ситуации.
Ответы
Ответ 1
Функции шаблона не могут быть частично специализированными. Решение состоит в том, чтобы обернуть его в структуру:
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();
}
Ответ 2
Очень поздно вечеринке здесь, но.
Способ сделать это, я думаю, концептуально проще, а также проще читать, просто делает разные значения вашего перечисления различными типами (внутри пространства имен, чтобы он был чистым) и использовал перегрузку функций (шаблона)
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;
}