Specializzazione del modello C ++ in base al valore del tempo di compilazione
-
12-12-2019 - |
Domanda
Mi sento la strada nella meta-programmazione del modello, lentamente e non sono sicuro di come implementare quanto segue:
// 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>();
.
Allo in compilazione conosterò quale valore enum il terzo tipo di modello è (invariante di compilazione), morto o vivo.È possibile definire due corpi per la funzione Registro, qualcosa del genere come:
// 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 ++ Modello di specializzazione con valore costante
Ma non sono stato in grado di capire come renderlo applicare a questa situazione.
Soluzione
Le funzioni del modello 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();
}
. Altri suggerimenti
Molto tardi per la festa qui, ma.
Un modo per farlo che penso sia concettualmente più semplice e anche più facile da leggere è semplicemente creare i diversi valori del tuo enum diverso tipi (all'interno di uno spazio dei nomi, per mantenerlo pulito) e prendereVantaggio del (modello) Sovraccarico di funzionamento:
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;
}
.
li chiami in questo modo:
int main() {
Register<int,int>(State::Dead());
Register<int,int>(State::Alive());
return 0;
}
.