让我说我有这个:
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答案 0 :(得分: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()
更好的是,在A的构造函数中移动.get()
调用,然后获取类型为A_helper
的参数。这将让您了解用户忘记使用MAKEA
宏的情况。
A* p = MAKEA(a | c);
与A* p = MAKEA( (a | c) );
和char mask = a | c; A* p = MAKEA(mask);
不同
答案 1 :(得分: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;
答案 2 :(得分:0)
尝试
enum E{
a = 1,
b = 2,
c = 4,
}
然后
A var(a | c)
将起作用
然后检查是否(例如)a
设置为&
,即if (mask & a) ...
答案 3 :(得分:0)
您需要从一组连续值生成位掩码。这很简单:
int mask(E e) {
return 1 << e;
}
现在你可以或掩码值一起调用你的函数:
A var(mask(a) | mask(b));