Masque de bits de l'instruction switch
J'ai ce code dans un article de mon projet:
enum myEnum
{
invalid = -1,
val1 = 1,
val2 = 2,
val3 = 4
};
int bitmask = val1 | val3;
if(bitmask & val1)
...
if(bitmask & val2)
...
if(bitmask & val3)
...
Ce qui est bien, et ça fonctionne parfaitement, mais je me suis toujours demandé si cela pouvait être fait par un interrupteur. Je pensais à quelque chose le long des lignes de cette:
int checkMask(int& mask)
{
for(int i = 0; mask; mask &= ~(1 << i++))
{
if(mask & (1 << i))
{
int ret = mask & (1 << i);
mask &= ~ret;
return ret;
}
}
return invalid;
}
#define START_BITMASK_SWITCH(x) int xcopy = x; while(xcopy) { switch(checkMask(xcopy))
#define END_BITMASK_SWITCH };
int bitmask = val1 | val3;
START_BITMASK_SWITCH(bitmask)
{
case val1:
...
break;
case val2:
...
break;
case val3:
...
break;
}
END_BITMASK_SWITCH
donc mes questions sont:
- ai-je viens de résoudre mon problème? je suppose que j'ai, mais c'est une solution propre?
- est-il un moyen plus simple d'y parvenir?
- est-ce une mauvaise idée de mélanger #définit et fonctions?
OriginalL'auteur Tom | 2011-07-07
Vous devez vous connecter pour publier un commentaire.
Je vois plusieurs problèmes:
if ((bitmask & (val2 | val3)) == val2)
)Il peut également être fait en beaucoup, beaucoup plus simple:
OriginalL'auteur sam hocevar
Non ce n'est pas une solution propre et de votre contexte, vous pouvez éviter de mélanger
#define
et les fonctions. Vous pouvez essayer en dessous de solution, si vous voulezswitch()
:OriginalL'auteur iammilind
Non, c'est (évidemment) pas une solution propre. Votre code d'origine était simple, n'est-ce pas de la boucle, et n'impliquent pas des cas à part "secret" macros ajouter étranges constructions de la langue.
Par "bizarre construire", je voulais dire le
START_BITMASK_SWITCH()
/END_BITMASK_SWITCH
des macros, qui:Il n'y a aucun avantage à votre solution, il ne fait qu'ajouter de ballonnements et de frais généraux (à la fois en termes de taille de code, et de la complexité, et les performances d'exécution) juste pour gratter que la démangeaison de pour une raison de vouloir utiliser un
switch
de faire quelque chose qu'il n'est pas très bien adapté pour le faire.Évidemment, c'est très subjectif, mais vous l'avez demander.
START_BITMASK_SWITCH est une mauvaise solution, mais ça ne fait pas obstacle à une bonne. Voir mon Indicateur de Position/enum approche ci-dessous.
Je suis d'accord avec vous détendre ici, c'est horrible, - il n'y a absolument rien à gagner de cette approche, mis à part quelques égratignures à la tête de quelques mois sur toute la ligne quand vous découvrez un bug.
"Si qui pourrait être fait"? Ce ? Quel a été le en appuyant sur les inconvénients causés par la syntaxe d'origine?
si cela pourrait être fait avec un commutateur, comme énoncé lol
OriginalL'auteur unwind
Un masque de bits est juste un tableau de booléens si vous voulez, et votre enum sont les indices. Pouvez-vous passer un tableau de bool? Non, vous ne le pouvez pas, car il peut représenter plusieurs états en même temps. Vous ne pouvait basculer l'ensemble de masque de bits comme avec n'importe quel nombre entier.
OriginalL'auteur Xeo
Vous pourriez faire un foreach construire où vous faire une itération sur les éléments de votre masque et de fournir une fonction avec une instruction switch.
OriginalL'auteur duedl0r
Ce n'est plus agréable avec C++0x forte enums, alors vous pouvez avoir
Position::ALPHA
etFlag::ALPHA
pour une meilleure appellation. Vous pouvez également utiliserconstexpr
en toute sécurité de votre masque de bits des valeurs d'Indicateur.Si ils ne le sont pas, vous ne pouvez pas utiliser bit à bit
operator|
cela ne fonctionne pas. Vous ne gérer qu'une seule position, mais il pourrait y avoir plus d': 11, puis vous utilisez uniquement la première 1.
OriginalL'auteur spraff