J'essaie d'utiliser les tuples boost pour éviter certains frais généraux de la fonction virtuelle, et je ne peux pas tout à fait le faire fonctionner. J'ai un vecteur de "handlers" qui essaye de gérer une entrée, et une fois que l'un d'entre eux retourne vrai, je ne veux pas appeler le reste d'entre eux.boost tuple itération partielle?
En premier lieu, la mise en œuvre virtuelle actuelle ressemble à ceci:
std::vector<Handler*> handlers;
//initialization code...
handlers.push_back(new Handler1);
handlers.push_back(new Handler2);
handlers.push_back(new Handler3);
//runtime code
for(std::vector<Handler*>::iterator iter = handlers.begin();
iter != handlers.end() && !(*iter)->handle(x); ++iter) {}
Depuis que j'ai tous les types à compiletime, je préférerais être en mesure d'exprimer cela comme un tuple, comme ceci:
boost::tuple<Handler1,Handler2,Handler3> handlers;
//runtime code
???
// should compile to something equivalent to:
// if(!handlers.get<0>().handle(x))
// if(!handlers.get<1>().handle(x))
// handlers.get<2>().handle(x);
Idéalement, il n'y aurait pas d'appels de fonction virtuelle et tout corps de fonction vide serait aligné. Il semble que ce soit presque possible avec boost::fusion for_each
, mais j'ai besoin du comportement de court-circuit où une fois que l'un des gestionnaires retourne vrai, le reste d'entre eux ne sont pas appelés.
Ça a l'air bien. Si je vais essayer de le faire sans C++ 11, je devrais juste lister manuellement les cas pour my_eval et les index? –
@E_G Vous pouvez les générer avec Boost.PP je présume. Pas vraiment amusant cependant. – Pubby
Sans C++ 11, créez simplement un modèle sur le nombre de gestionnaires à appeler total et le nombre restant. 'get' la différence. Recurse et se spécialise sur 0 gestionnaires laissés à l'échec et non recurse. – Yakk