Pergunta

Recentemente, me deparei com algumas funções em que você pode passar várias enumes como esta:

myFunction(One | Two);

Já que acho que essa é uma maneira muito elegante, tentei implementar algo assim:

void myFunction(int _a){
    switch(_a){
        case One:
            cout<<"!!!!"<<endl;
            break;
        case Two:
            cout<<"?????"<<endl;
            break;
    }
}

Agora, se eu tentar chamar a função com um | Segundo, quero que os dois casos de switch sejam chamados. Não sou muito bom com operadores binários, então não sei realmente o que fazer. Quaisquer idéias seriam ótimas!

Obrigado!

Foi útil?

Solução

Para isso, você tem que fazer enumes como:

enum STATE {
  STATE_A = 1,
  STATE_B = 2,
  STATE_C = 4
};

O valor do elemento enum do IE deve estar no poder de 2 para selecionar um caso válido ou se a instrução.

Então, quando você gosta:

void foo( int state) {

  if ( state & STATE_A ) {
    //  do something 
  }

  if ( state & STATE_B ) {
    //  do something 
  }

  if ( state & STATE_C ) {
    //  do something 
  }   
}

int main() {
  foo( STATE_A | STATE_B | STATE_C);
}

Outras dicas

Os operadores bitwise se comportam bem apenas com os poderes de 2:

  0010
| 0100
------
  0110  // both bits are set


  0110
& 0100
------
  0100  // nonzero, i.e. true: the flag is set

Se você tentar fazer o mesmo com números arbitrários, obterá resultados inesperados:

  0101  // 5
| 1100  // 12
------
  1101  // 13

Que contém os números possíveis (arbitrários) como sinalizadores definidos: 0001 (1), 0100 (4), 0101 (5), 1000 (8), 1001 (9), 1100 (12), 1101 (13)

Então, em vez de dar duas opções, você apenas deu seis.

Normalmente, os argumentos combinados dessa maneira são sinalizadores (um valor com um único conjunto de bits) com um valor decimal de 1, 2, 4, 8, etc. Supondo que um e dois sigam essa regra, você não pode usar um interruptor para verificar Ambas. Os interruptores seguem apenas um caminho. Seu argumento combinado não é igual a um ou dois, mas uma combinação deles (1 | 2 == 3). Você pode verificar se um ou dois está definido como este:

if (_a & One)
{

}
if (_a & Two)
{

}

Lembre -se de que uma enumeração padrão sem valores explícitos contam apenas para cima, não usará o próximo bit. Se o seu próximo valor definido for três, provavelmente será igual a 3, o que não é um valor de um único bit e depois agirá como se você tivesse passado os dois sinalizadores (um | dois) para a função. Você precisará definir os valores da enumeração.

Você deve dividir os possíveis "tokens" (não sobrepostos, é claro ... Use Power of 2):

if (_a & One) { ... }

Não é elegante realmente fazer o que você deseja com 1 Switch Declarenting: Split usando if declarações.

É melhor você fazer isso com um conjunto de declarações if ...

ou seja

if ( _a & ONE )
{
   // Do stuff.
}
if ( _a & TWO )
{
  // Do other stuff.
}

EDIT: Você também pode fazê -lo em uma declaração de troca, mas seria um pesadelo. Você precisaria de algo assim

switch( _a )
{
case ONE:
   // Handle ONE.
   break;

case TWO:
   // Handle TWO.
   break;

case ONE | TWO:
   // Handle ONE.
   // Handle TWO.
   break;
};

É relativamente sensato por apenas duas opções, mas uma vez que você obtém mais do que isso começa a balançar fora de controle. Se você tiver 32 opções, teria uma instrução SWITCH que provavelmente se encaixaria em qualquer máquina. Tudo na solução "se" é muito mais limpo e muito mais sã :)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top