C ++ Spécialisation des modèles basés sur la valeur de l'heure de la compilation
-
12-12-2019 - |
Question
Je ressens mon chemin dans le modèle méta-programmation, lentement et je ne sais pas comment implémenter les éléments suivants:
// 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>();
Au moment de la compilation, je saurai quelle valeur ENUM Le troisième type de modèle est (Invariart de compilation), mort ou vivant.Est-il possible de définir deux corps pour la fonction de registre, quelque chose comme:
// 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 ... }
J'ai cherché à regarder: spécialisation de modèle C ++ avec valeur constante
Mais je n'ai pas pu savoir comment le faire s'appliquer à cette situation.
La solution
Les fonctions de modèle ne peuvent pas être partiellement spécialisées.La solution consiste à envelopper dans une structure:
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();
}
Autres conseils
très tard à la fête ici, mais.
Un moyen de faire cela que je pense être plus simple et plus facile à lire consiste simplement à simplifier les différentes valeurs de votre énumérum différent types (à l'intérieur d'un espace de noms, de le garder propre) et de prendreAvantage du (modèle) Fonction Surcharge:
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;
}
Vous les appelez comme ceci:
int main() {
Register<int,int>(State::Dead());
Register<int,int>(State::Alive());
return 0;
}