我正在用C++进行枚举,以使用二进制标志制作一个有限状态机。看起来像:
enum VStates
{
NEUTRAL = 0x00000000, // 000000
// Physical Status
DRY = 0x00000001, // 000001
WET = 0x00000002, // 000010
HOT = 0x00000004, // 000100
COLD = 0x00000008, // 001000
BURNED = 0x00000016, // etc..
FROZEN = 0x00000032,
EROS = 0x00000064, //
THANATOS = 0x00000128, //
SLEEP = 0x00000256,
STUNNED = 0x00000512,
PARALYZED = 0x00001024,
POISONED = 0x00002048, //
BLIND = 0x00004096,
SOFT = 0x00008192, // Flexible
TOUGH = 0x00016384, // Resistent
MAGNETIZED = 0x00032768,
POSSEDERUNT = 0x00131072, //
// Mental Status
ANGRY = 0x00262144,
DRUGGED = 0x00524288, // Drugs Meaning
HORNY = 0x01048576, // Sexual Meaning
// Material Status
METAL = 0x02097152,
WOOD = 0x04194304,
GLASS = 0x08388608,
AIR = 0x16777216,
EARTH = 0x33554432,
DUST = 0x67108864,
LIGHT = 0x134217728,
SHADOW = 0x268435456,
WATER = 0x536870912,
// Total Status
PROTECTED = 0x1073741824,
INVULNERABLE = 0x2147483648
};
有些状态是不兼容的,所以我使用按位运算符来管理它们。现在,我的编译器说:
warning: integer constant is too large for 'long' type
这是声明此枚举的正确方法吗?我喜欢避免警告,因此,如何解决此问题?
最佳答案
(注意:为使答案完整,我将添加一些我没有花时间注意到的内容,但其他人指出:您使用的是0x
前缀,这意味着您的数字将被解释为十六进制。实际上是2的幂,并且您的位标志测试将无法正常工作!)
如果您的枚举已失去控制,请不要使用枚举类型。使用类似 std::bitset
的东西。然后,您的枚举可以只是名称集中的简单编号列表,而您将不会成倍地耗尽枚举空间!
例如:
enum VState {
NEUTRAL,
DRY,
WET,
COLD,
BURNED,
FROZEN,
/* ... */
VState_Max
};
bitset<VState_Max> state;
state[COLD] = true;
if (state[COLD]) {
cout << "I am cold\n";
}
现在,您的枚举很小,可以维护,您不必担心会在64位平台上运行。
我注意到您在原始示例中将NEUTRAL的值设置为“0”。如果您的意图是可以将其与其他功能结合使用……例如能够成为
state = NEUTRAL | INVULNERABLE | SHADOW
并单独测试NEUTRAL
,那将是以前无法实现的。现在它将...您只需将其保留在为位集编制索引的枚举中即可。但是,如果打算将其用作“nothing set”的名称,则可以将其从枚举中删除,而无需测试是否设置了以下任何位:
if (state.none()) {
// we are in the "NEUTRAL" state of nothing set...
}
...如果您想将所有位设置为false,则可以使用:
state.reset();