您的第一个选择是使用constexpr 而不是枚举:
constexpr size_t NUM_GHOSTS = 4;
你可以把它放在适当的上下文中,比如 GameConsts struct:
struct GameConsts {
static constexpr size_t NUM_GHOSTS = 4;
};
那么就不需要强制转换了:
Ghost ghosts[GameConsts::NUM_GHOSTS];
如果您确实需要一个枚举,因为您有一个要一起管理的相关值的列表,那么您可以使用无范围的枚举(即从enum class 中删除class 并使用普通的普通-旧的enum) 但将其放在结构中以保留上下文。我将在这里使用另一个枚举的示例,管理几个相关的值。
enum class GameKeys: char { UP = 'W', RIGHT = 'D', DOWN = 'X', LEFT = 'A' };
static_cast 的重复使用可能会发生在上述枚举中,在这样的 switch-case 中:
char key_pressed;
// ...
switch(key_pressed) {
case static_cast<char>(GameKeys::UP): // ...
break;
case static_cast<char>(GameKeys::RIGHT): // ...
break;
case static_cast<char>(GameKeys::DOWN): // ...
break;
case static_cast<char>(GameKeys::LEFT): // ...
break;
}
为避免重复使用static_cast,您可以使用:
选项 1:在结构中使用简单的无范围枚举
struct GameKeys {
enum: char { UP = 'W', RIGHT = 'D', DOWN = 'X', LEFT = 'A' };
};
而且由于旧式枚举可以隐式转换为其基础类型,您可以摆脱转换:
switch(key_pressed) {
case GameKeys::UP: // ...
break;
case GameKeys::RIGHT: // ...
break;
case GameKeys::DOWN: // ...
break;
case GameKeys::LEFT: // ...
break;
}
选项 2:添加自己的转换函数
如果您确实喜欢或必须使用enum class,您可能有一个简单的转换函数,复制粘贴只是调用该函数,比完整的static_cast 语法更简单:
enum class GameKeys: char { UP = 'W', RIGHT = 'D', DOWN = 'X', LEFT = 'A' };
// a simple "val" function - specific for our GameKeys
constexpr char val(GameKeys key) { return static_cast<char>(key); }
还有:
switch(key_pressed) {
case val(GameKeys::UP): // ...
break;
case val(GameKeys::RIGHT): // ...
break;
case val(GameKeys::DOWN): // ...
break;
case val(GameKeys::LEFT): // ...
break;
}
如果您选择最后一个选项,您可能希望将其推广到任何类型的enum,使用this code:
// creating a "concept" for enums
template<typename E>
concept EnumType = std::is_enum_v<E>;
// creating a generic "val" function for getting the underlying_type value of an enum
template<EnumType T>
constexpr auto val(T value) {
return static_cast<std::underlying_type_t<T>>(value);
}
选项 3:投射到枚举而不是从枚举
根据 cmets 中的 @Nathan Pierson 和 @apple apple 的建议,可以使用 this code 对枚举进行强制转换:
char key_pressed = 'E';
// cast to the enum
GameKeys key = static_cast<GameKeys>(key_pressed);
switch(key) {
case GameKeys::UP: // ...
break;
case GameKeys::RIGHT: // ...
break;
case GameKeys::DOWN: // ...
break;
case GameKeys::LEFT: // ...
break;
default: // ignore any other keys
break;
}
即使key_pressed 不是任何枚举值,这也应该可以正常工作,因为我们有一个固定的枚举(具有声明的基础类型,请注意枚举类始终是固定的,即使没有明确声明)。另见:What happens if you static_cast invalid value to enum class?