0

私がこれを持っているとしましょう:

enum E{ 
a,
b,
c,
total
}

class A {
char mask; // supposed to contains combinations of values of the enum, like a or c, etc
}

ユーザーフレンドリーな方法でオブジェクトAを構築するための適切なソリューションはありますか?たとえば、私は次のことができます。

A(E e) {
mask = 1 << e;
}

ただし、これは、列挙型の1つの要素のみからマスクを作成する場合にのみ機能します。理想的には、ユーザーは次のようなことを実行できます。

A* a = new A(a | c)

これにより、自動的に作成されます

mask = 1 << a | 1 << c;

これを正しく行う方法について何かアイデアはありますか?ありがとう

編集

悲しいことに、私は最初の列挙型を制御できず、値は1ずつ増加しています

4

4 に答える 4

1

さて、簡単な方法と醜い方法があります。

簡単な方法は、ビットを重複しないものとして定義することです。例:

enum E
{ 
   a = 1 << 0,
   b = 1 << 1,
   c = 1 << 2,
   total = 1 << 3 // or a | b | c, not sure what the intent was
};

醜い方法:

#define MAKEA(x) (new A((E_helper() | x).get()))

ここで、E_helperはをオーバーライドするクラスですoperator|(enum E)

class E_helper
{
    unsigned accum;
public:
    explicit E_helper(unsigned initial = 0) : accum(initial) {}
    unsigned get() const { return accum; }
    E_helper operator|(enum E e) const { return E_helper(accum | (1 << (unsigned)e)); }
};

そして、あなたのユーザーは言うことができます

A* p = MAKEA(a | c);

これはに拡張されます

A* p = (new A((A_helper() | a | c).get());

この一連のイベントを引き起こします

A_helper.operator|(a).operator|(c).get()

.get()さらに良いことに、呼び出しをAのコンストラクター内に移動します。コンストラクターは、型の引数を取りますA_helperMAKEAこれにより、ユーザーがマクロの使用を忘れた場合を把握できます。

ただし、醜い方法では直感に反する動作が発生することに注意してください。たとえば、とA* p = MAKEA(a | c);は異なりますA* p = MAKEA( (a | c) );char mask = a | c; A* p = MAKEA(mask);

于 2012-10-25T19:59:24.153 に答える
1

型を維持し、ビット単位のサポートを提供するため|&^マクロで次の演算子を記述し、通常、プロジェクトの列挙型でそれらを使用します。

enum E {
    a = 1 << 0,
    b = 1 << 1,
    c = 1 << 2,
    total = a | b | c
};
E operator | (E lhs, E rhs ) {
    return static_cast<E>( static_cast<int>(lhs) | static_cast<int>(rhs) );
}
E operator & (E lhs, E rhs ) {
    return static_cast<E>( static_cast<int>(lhs) & static_cast<int>(rhs) );
}
E operator ^ (E lhs, E rhs ) {
    return static_cast<E>( static_cast<int>(lhs) ^ static_cast<int>(rhs) );
}
E operator ~ (E e ) {
    return static_cast<E>( ~static_cast<int>(e) );
}
E& operator |= (E& lhs, E rhs ) {
    return lhs = static_cast<E>( static_cast<int>(lhs) | static_cast<int>(rhs) );
}
E& operator &= (E& lhs, E rhs ) {
    return lhs = static_cast<E>( static_cast<int>(lhs) & static_cast<int>(rhs) );
}
E& operator ^= (E& lhs, E rhs ) {
    return lhs = static_cast<E>( static_cast<int>(lhs) ^ static_cast<int>(rhs) );
}

今あなたは持っているかもしれません:

void test( E e );
test( a | b );
E e = c;
e |= b;
e = e & d;
e ^= a;
e = ~e;
于 2012-10-25T20:15:42.433 に答える
0

試す

enum E{ 
a = 1,
b = 2,
c = 4,

}

それで

A var(a | c)

動作します

次に、(たとえば)aが設定されているかどうかを確認するには、次を使用します&if (mask & a) ...

于 2012-10-25T19:59:19.130 に答える
0

連続する値のセットからビットマスクを生成する必要があります。それは簡単です:

int mask(E e) {
    return 1 << e;
}

これで、関数を呼び出すために値を一緒にまたはマスクすることができます。

A var(mask(a) | mask(b));
于 2012-10-25T20:05:00.117 に答える