9

私は最近、次のような複数の列挙型を渡すことができるいくつかの関数に出くわしました。

myFunction(One | Two);

これは本当にエレガントな方法だと思うので、自分でそのようなものを実装しようとしました。

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

今、One|で関数を呼び出そうとすると 2つ目は、両方のスイッチケースが呼び出されるようにすることです。私は二項演算子があまり得意ではないので、どうしたらよいかわかりません。どんなアイデアでも素晴らしいでしょう!

ありがとう!

4

5 に答える 5

14

そのためには、次のような列挙型を作成する必要があります。

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

つまり、enum 要素の値は、有効な case または if ステートメントを選択するために 2 のべき乗である必要があります。

だからあなたが好きなとき:

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);
}
于 2009-12-09T14:01:46.283 に答える
9

ビット演算子は 2 のべき乗でのみ適切に動作します。

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


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

任意の数値で同じことをしようとすると、予期しない結果が得られます。

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

セットフラグとして可能な(任意の)数値を含む:0001(1)、0100(4)、0101(5)、1000(8)、1001(9)、1100(12)、1101(13)

つまり、2 つのオプションを指定する代わりに、6 つのオプションを指定しただけです。

于 2009-12-09T14:21:08.133 に答える
3

通常、そのように組み合わされる引数は、1、2、4、8 などの 10 進数値を持つフラグ (単一ビットが設定された値) です。One と Two がこの規則に従うと仮定すると、スイッチを使用してチェックすることはできません。両方。スイッチは 1 つのパスのみに従います。組み合わせた引数は One または Two ではなく、それらの組み合わせ (1 | 2 == 3) です。One または Two が次のように設定されているかどうかを確認できます。

if (_a & One)
{

}
if (_a & Two)
{

}

明示的な値を持たない標準の列挙型は、次のビットを使用せず、単に上向きにカウントされることに注意してください。次に定義した値が Three の場合、1 ビットの値ではない 3 になる可能性が高く、関数に両方のフラグ (One | Two) を渡したかのように動作します。列挙型の値を自分で設定する必要があります。

于 2009-12-09T13:59:28.940 に答える
2

可能な「トークン」を分割する必要があります(もちろん、重複しない... 2の累乗を使用します)。

if (_a & One) { ... }

エレガントではありませんが、1つのswitchステートメントで必要なことを実際に実行しますif。ステートメントを使用して分割します。

于 2009-12-09T13:55:17.620 に答える
2

if ステートメントのセットでそれを行う方が良いです...

すなわち

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

編集: switch ステートメントでも実行できますが、それは悪夢です。このようなものが必要です

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

case TWO:
   // Handle TWO.
   break;

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

2つのオプションだけでは比較的健全ですが、それ以上になると、制御不能になり始めます. 32 個のオプションがある場合、switch ステートメントはどのマシンにも適合しそうにありません。「if」ソリューションのすべては、はるかにクリーンで、はるかに正気です:)

于 2009-12-09T13:55:47.230 に答える