枚举类作为数组索引
enum class as array index
我做了一个枚举:
enum class KeyPressSurfaces {
KEY_PRESS_SURFACE_DEFAULT,
KEY_PRESS_SURFACE_UP,
KEY_PRESS_SURFACE_DOWN,
KEY_PRESS_SURFACE_LEFT,
KEY_PRESS_SURFACE_RIGHT,
KEY_PRESS_SURFACE_TOTAL
};
后来我尝试在下面键入定义一个数组,但我收到了错误,size of array 'KEY_PRESS_SURFACES' has non-integral type 'KeyPressSurfaces'
SDL_Surface*KEY_PRESS_SURFACES[KeyPressSurfaces::KEY_PRESS_SURFACE_TOTAL];
我很好地理解了错误,但我不知道将KeyPressSurfaces
移动到何处以限定枚举中的常量。
我也意识到我可以用enum
而不是enum class
,但我觉得这应该有效,我想学习如何做到这一点。
任何回应/建议?
作用
域enum
s(enum class
)不能隐式转换为整数。您需要使用static_cast
:
SDL_Surface*KEY_PRESS_SURFACES[static_cast<int>(KeyPressSurfaces::KEY_PRESS_SURFACE_TOTAL)];
您可以使用
模板函数将enum
转换为int
,您将获得更具可读性的代码:
#include <iostream>
#include <string>
#include <typeinfo>
using namespace std;
enum class KeyPressSurfaces: int {
KEY_PRESS_SURFACE_DEFAULT,
KEY_PRESS_SURFACE_UP,
KEY_PRESS_SURFACE_DOWN,
KEY_PRESS_SURFACE_LEFT,
KEY_PRESS_SURFACE_RIGHT,
KEY_PRESS_SURFACE_TOTAL
};
template <typename E>
constexpr typename std::underlying_type<E>::type to_underlying(E e) {
return static_cast<typename std::underlying_type<E>::type>(e);
}
int main() {
KeyPressSurfaces val = KeyPressSurfaces::KEY_PRESS_SURFACE_UP;
int valInt = to_underlying(val);
std::cout << valInt << std::endl;
return 0;
}
我在这里to_underlying
功能
您可以在数组上工作:
/** brief It's either this or removing the "class" from "enum class" */
template <class T, std::size_t N>
struct EnumClassArray : std::array<T, N>
{
template <typename I>
T& operator[](const I& i) { return std::array<T, N>::operator[](static_cast<std::underlying_type<I>::type>(i)); }
template <typename I>
const T& operator[](const I& i) const { return std::array<T, N>::operator[](static_cast<std::underlying_type<I>::type>(i)); }
};
删除 class
关键字或显式转换为整型类型。
在其他响应的基础上,另一种选择是包装 c 样式数组的简单模板化类。通过下面的 EnumArray 示例,任何带有 kMaxValue
的enum class
都可以用作索引。
在我看来,提高的可读性值得引入模板。
template <class IndexType, class ValueType>
class EnumArray {
public:
ValueType& operator[](IndexType i) {
return array_[static_cast<int>(i)];
}
const ValueType& operator[](IndexType i) const {
return array_[static_cast<int>(i)];
}
int size() const { return size_; }
private:
ValueType array_[static_cast<int>(IndexType::kMaxValue) + 1];
int size_ = static_cast<int>(IndexType::kMaxValue) + 1;
};
enum class KeyPressSurfaces {
KEY_PRESS_SURFACE_DEFAULT,
KEY_PRESS_SURFACE_UP,
KEY_PRESS_SURFACE_DOWN,
KEY_PRESS_SURFACE_LEFT,
KEY_PRESS_SURFACE_RIGHT,
KEY_PRESS_SURFACE_TOTAL,
kMaxValue = KEY_PRESS_SURFACE_TOTAL
};
int main() {
EnumArray<KeyPressSurfaces, int> array;
array[KeyPressSurfaces::KEY_PRESS_SURFACE_DEFAULT] = 5;
std::cout << array[KeyPressSurfaces::KEY_PRESS_SURFACE_DEFAULT] << std::endl;
return 0;
}
您可以使用命名空间和匿名枚举。因此,您可以摆脱这些丑陋的前缀并使用枚举项作为索引。
namespace KeyPressSurfaces
{
enum
{
DEFAULT = 0,
UP,
DOWN,
LEFT,
RIGHT,
TOTAL
};
}
SDL_Surface* KEY_PRESS_SURFACES[KeyPressSurfaces::TOTAL];
使用结构成员而不是枚举。
struct KeyPressSurfaces {
static constexpr int KEY_PRESS_SURFACE_DEFAULT = 0;
static constexpr int KEY_PRESS_SURFACE_UP= 1;
static constexpr int KEY_PRESS_SURFACE_DOWN = 2;
static constexpr int KEY_PRESS_SURFACE_LEFT = 3;
static constexpr int KEY_PRESS_SURFACE_RIGHT = 4;
static constexpr int KEY_PRESS_SURFACE_TOTAL = 5;
};
或者,将它们放在具有相同逻辑的命名空间中,您可以从中受益 using namespace
.
namespace KeyPressSurfaces {
constexpr int KEY_PRESS_SURFACE_DEFAULT = 0;
constexpr int KEY_PRESS_SURFACE_UP= 1;
constexpr int KEY_PRESS_SURFACE_DOWN = 2;
constexpr int KEY_PRESS_SURFACE_LEFT = 3;
constexpr int KEY_PRESS_SURFACE_RIGHT = 4;
constexpr int KEY_PRESS_SURFACE_TOTAL = 5;
}
SDL_Surface* KEY_PRESS_SURFACES[KeyPressSurfaces::KEY_PRESS_SURFACE_TOTAL];
除了当前接受的答案之外,您还可以编写一个函数来获取对表面的引用:
enum class KeyPressSurface
{
DEFAULT,
UP,
DOWN,
LEFT,
RIGHT,
TOTAL
};
// This is using static_cast like the accepted answer
std::array<SDL_Surface *, static_cast<int>(KeyPressSurface::TOTAL)> keyPressSurfaces;
// Function to get a reference to a surface
SDL_Surface *&getKeyPressSurface(KeyPressSurface surface)
{
return keyPressSurfaces[static_cast<int>(surface)];
}
现在,您可以使用枚举类干净地获取表面:
// assignment
getKeyPressSurface(KeyPressSurface::UP) = SDL_LoadBMP("lamp.bmp");
// or get a value
SDL_Surface *currentSurface = getKeyPressSurface(KeyPressSurface::RIGHT);
或者
你可以用map
替换你的array
,这也意味着你可以摆脱KEY_PRESS_SURFACE_TOTAL
:
enum class KeyPressSurfaces {
KEY_PRESS_SURFACE_DEFAULT,
KEY_PRESS_SURFACE_UP,
KEY_PRESS_SURFACE_DOWN,
KEY_PRESS_SURFACE_LEFT,
KEY_PRESS_SURFACE_RIGHT
};
std::map<KeyPressSurfaces, SDL_Surface*> KEY_PRESS_SURFACES;
相关文章:
- 数组索引的值没有增加
- 并行用于C++17中数组索引范围内的循环
- 数组索引重载错误
- 通过指针与数组引用扩展数组索引序列
- SIGSEGV, 分段错误. 而 printf() 数组索引的值
- 缓冲区溢出 - 数组索引越界(严重)
- 为什么C++数组索引值是有符号的,而不是围绕size_t类型构建的(或者我错了)
- 查找下一个具有真值C++的数组索引
- 在编译时自动生成用于稀疏数组索引的switch语句
- 在数组索引上引发异常
- C++ 将二维数组索引与条件语句中的函数值进行比较
- 平衡数组索引,同时从左和右对数组求和
- 为什么C ,Devstudio,数组索引工作
- 如何对同一数组索引下的结构成员进行排序?
- 我想返回数组索引,而不是数组值
- C++相当于 Python 的:用于数组索引
- 分段错误:为什么这里的数组索引越界了
- 数组索引在地图上不是整数
- 根据用户输入的每个字母添加到数组索引
- C 数组索引