ビットマスクを列挙値に使用することは可能ですが、作成方法はわかりません。ビットマスクを使用した列挙値の結合
enum State
{
minimizing = 0,
maximizing,
minimized,
maximized
};
状態が常にState.minimized
またはState.maximized
で、サイズ変更で追加の状態を持つことができます。
ビットマスクを列挙値に使用することは可能ですが、作成方法はわかりません。ビットマスクを使用した列挙値の結合
enum State
{
minimizing = 0,
maximizing,
minimized,
maximized
};
状態が常にState.minimized
またはState.maximized
で、サイズ変更で追加の状態を持つことができます。
私はmyState
のタイプがenum State
であると仮定します。
伝統的にはenum
を使用すると、このタイプの変数で使用できる定数値を作成できます。変数myState
をの組み合わせに設定する場合は、enum
に定義されている値を使用します。
enum
は1,2,4、および8を有効な値として定義しますが、変数を4 | 2 = 6. Cは、enum
のすべてのタイプに対してint
というタイプの実装を使用していますが、C++ではそうではありません。 myState = 6
はC++では無効です。実際には、myState = 4
はC++では有効ではありません。明示的にキャストするか、enum
の定数名のいずれかを使用する必要があります。
Cでも可能ですが、myState
をそのタイプで定義されていない値(たとえば6)に設定することはお勧めしません。あなたのケースでは
、結果的には以下のようになりそうですソリューション:
typedef enum {
OTHER,
MINIMIZED,
MAXIMIZED
} win_size_t;
typedef struct {
win_size_t current;
win_size_t next;
} state_t;
state_t myState;
こうすることで、あなたはフィールドundependently current
とnext
に書き込むことができます。
ビットフィールドを残したい場合は、構造体の要素のサイズをビット単位で設定できます。ビットフィールドの実装はコンパイラによって異なりますが、危険です。コンパイラがビットフィールドに列挙型を持つことを受け入れるかどうかはわかりません(enum
はint
です)。
typedef struct {
win_size_t current : 2; // not tested
win_size_t next : 2;
} state_t;
上記の解決策はもちろん有効です。私のポイントは、変数myState
にタイプとしてenum State
がある場合、その値にはenum
のメンバーのみを使用し、組み合わせには使用しないでください。
myState
には別のタイプがあります。何を知っていますか?
myState
がenum State
タイプでない場合は、組み合わせてあなたのenum
で定義された定数を使用することができます。あなたが希望する可能性はありません
myState = MAXIMIZED | MINIMIZING;
しかし、また、物事:
enum State {
MINIMIZING = (1u << 0),
MAXIMIZING = (1u << 1),
MINIMIZED = (1u << 2),
MAXIMIZED = (1u << 3),
};
unsigned int myState = 0;
myState |= MAXIMIZED; // sets that bit
myState &= ~MAXIMIZED; // resets that bit
これを使用すると、1つの割り当てで2つのことを行うことができます
myState = MAXIMIZED | MINIMIZED; // does that make sense?
この効果は、列挙のすべてのフィールドを指定することで得ることができ、ビットマスク効果を得るために2の累乗で増加します。たとえば、あなたの場合:
enum State
{
minimizing = 1,
maximizing = 2,
minimized = 4,
maximized = 8
};
したがって、(State.maximized | State.minimizing)
の組み合わせを使用できます。ただし、State.maximized
またはState.minimized
という制限は適用されません。あなたがそれをしたいのであれば、それらを1ビットに変換することができますが、この例では最大化も最小化もしない場合があると思います。
通常はシフト – justin
を使用して書かれていますが、どうすれば使用できますか?私のように: 'myState = minimized; if(isMaximizing){myState = maximizing} '最小化された状態を失うことなく、最大化状態を設定したい –
次に、' myState | = maximizing; 'を使うことができます。これは、他のビットに触れることなく興味のあるビットを設定します。ゼロにするには、 'myState&=〜maximizing;'を使用します。比較を行うときは注意してください。 'myState == minimized'は動作しません。' myState&minimized == minimized'(または '!= 0')が必要です。私があなたの場合は、1つのフィールドが「現在の状態」で、もう1つが「次の状態」であるとみなします。 – Gauthier
のような、あなたの列挙のすべての値に異なるビットを使用します。次に
enum State
{
minimizing = 0x01, // 00000001
maximizing = 0x02, // 00000010
minimized = 0x04, // 00000100
maximized = 0x08 // 00001000
}:
、あなたはビット単位または(minimizing | maximized
)とビット単位のAND(bool is_minimized = (flags & minimized);
)との値のためのテストで複数の値を組み合わせることができます。
味の質問ですが、私は ''(1u << 0) ''(1u << 1) ''(1u << 2) ''(1u << 3) 'を好む。どのビットを意味するのかがはっきりしています。 – Gauthier
16進法で値を定義するのはなぜですか? 'minimizing = 1'も動作します –
@NatanYellin:そうですが、もう1つの状態を追加し、10進数を使用する場合は16を書きます。2ビット、ビット4を設定したいとします。結果は10進数で18で、0x12よりも読みにくくなります(明らかでない場合は、2398の小数点にどのビットがセットされているかを確認してください)。どのビットが設定されているかに関心がある場合は、16進数を使用してください。 – Gauthier
私はVS2012でこれを試してみました、ビットフィールドを使用している場合、オプティマイザはビットを正しく組み合わせるように見えます。 1つの命令で両方のビットを設定
次いでstruct BITS { int x: 1; int y:1; };
BITS b;
b.x = b.y = 1;
。
ありがとう!私はオプション#1に行きました。確かに、それは感知しません。 MINIMIZED'が可能であり、2つの列挙型を持つことが可読性に優れているためです。 –
列挙をビットフィールドに限定することは未定義の動作であり、結果はコンパイラによって異なります。私が間違っている場合はまた、私を修正してください。 –
@DavidTóthあなたは正しいと思われる、これのためにありがとう! https://stackoverflow.com/a/33590935/108802 – Gauthier