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 递增 1

4

4 回答 4

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 回答
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()))

whereE_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_helper。这将让您捕捉到用户忘记使用MAKEA宏的情况。

但是请注意,丑陋的方式会暴露出违反直觉的行为。例如,A* p = MAKEA(a | c);不同于A* p = MAKEA( (a | c) );char mask = a | c; A* p = MAKEA(mask);

于 2012-10-25T19:59:24.153 回答
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 回答