J'écris une sorte de compilateur source à source et à un moment donné, je produis une succession d'instructions if
qui me permettent d'instancier l'objet modèle correct. Ces objets nécessitent un bool...
, donc certains peuvent avoir juste un, d'autres plusieurs. Il ressemble à:Type de modèle Variadic à partir de valeurs dynamiques
if(unknow_at_compilation==1){
if(unknown2 == 3){
My_obj<true> A;
My_obj<true, false> B;
/*do something X*/
}else{
My_obj<true> A;
My_obj<false, false> B;
/*do same thing X*/
}else{
if(unknown2 == 3){
My_obj<false> A;
My_obj<true, true> B;
/*do same thing X*/
}else{
My_obj<false> A;
My_obj<false, true> B;
/*do same thing X*/
}
}
mais avec beaucoup plus de conditions et d'objets. Je ne peux pas utiliser le polymorphisme et le pointeur puisque la performance est un point critique dans mon application et que l'objet A
et B
sont fortement utilisés.
Au lieu de cette succession complexe si if
je voudrais utiliser la métaprogrammation. Cependant, je fais face à de sérieuses difficultés ... Pendant ma génération, je connais le nombre d'objets dont j'ai besoin et combien de "bool" il a besoin.
La première étape a consisté à résumer le « faire quelque chose » part à une structure de modèle prenant ensembles de booléen:
template<bool... val>
struct bool_set{};
template<typename T1, typename T2>
struct struct_do_something;
template<bool... b1, bool... b2>
struct struct_do_something<bool_set<b1...>, bool_set<b2...>>
{
static void do_something(){
My_obj<b1...> i;
My_obj<b2...> j;
/*Do something*/
}
};
Ces pièces fonctionne et je peux l'appeler comme ça (par exemple): struct_do_something<bool_set<true, true>, bool_set<false, false>>::do_something();
Ensuite, j'ai écrit une structure qui génère un seul bool_set
en utilisant les conditions.
template<bool... static_vals> //bool values of the currently created bool_set
struct bool_set_generator{
template<typename... Bool>
static void select(bool v1, Bool... dynamic_vals) //Conditions in parameters
{
if(v1)
return bool_set_generator<static_vals..., true>::select(dynamic_vals...);
else
return bool_set_generator<static_vals..., false>::select(dynamic_vals...);
}
static void select(){
/*I have a bool_set here -> I can "do something"*/
struct_do_something<bool_set<static_vals...>>::do_something();
}
};
De toute évidence, il est pas fini: je peux générer un seul bool_set
donc mon idée était de stocker les bool_set
déjà créé + celui qui est actuellement créé comme ça:
template <typename... Created, bool... static_val>
mais le compilateur (g ++ 5.4 avec -std = C++ 11) me dit parameter pack ‘Created’ must be at the end of the template parameter list
et je le change avec l'autre, il dit la même chose ...
Est-ce que quelqu'un a une idée? En fin de compte, je voudrais appeler ma fonction comme ça (ou équivalent): (d'une fonction)
generate_the_do_something<>::call({cond1, cond2}, {cond3, cond4, cond5});
Chaque liste initialiseur est un bool_set
et ce generate_the_do_something
est une structure qui permettra de créer le bool_set
et appelez le do_something()
avec eux.
Merci beaucoup!J'ai réussi à le modifier pour ajouter des paramètres à la fonction "func" :) Je n'ai finalement pas besoin du 'std :: enable_if' mais c'est un bon exemple pour comprendre comment cela fonctionne et quand l'utiliser, merci encore :) – Viridya