检查范围的枚举是否包含一个值

发布于 2025-01-26 17:42:55 字数 559 浏览 2 评论 0原文

我还没有看到有关枚举问题的明确答案。可以说我有枚举:

enum class TileType
{
    WALL= 'W',
    PASSAGE= 'P',
    MONSTER = 'M',
    CRYSTAL= 'C',
};

我想打字并用char做新的枚举 假设输入字符是未定义的:

char id = 'A';

现在,当我打字时,有一个不确定的行为:

TileType type = static_cast<TileType>(id);

这就是为什么我想检查ID是否是枚举的有效值

//check if enum contains id
bool checkID(char id){...}

,现在我有几个想法要做就像对我杀人。我也找不到迭代课程以使支票变得容易的方法,但我认为这是不可能的。

有没有办法可以轻松检查枚举是否包含ID,以便我可以决定是否可以打字?还是我应该喜欢开关语句并检查每种情况吗?

I haven't seen a clear answer to this question about enums. Lets say I have an enum:

enum class TileType
{
    WALL= 'W',
    PASSAGE= 'P',
    MONSTER = 'M',
    CRYSTAL= 'C',
};

and I want to typecast and make a new enum with a char
Lets say the input char is undefined it the enum:

char id = 'A';

Now when I typecast it there is an undefined behaviour:

TileType type = static_cast<TileType>(id);

Thats why I want to check if the id is a valid value for an enum

//check if enum contains id
bool checkID(char id){...}

Now I have a couple ideas to do it but they seem like over kill to me. I also couldn't find a way to iterate over the enum class to make the check easy but I don't think that's possible.

Is there a way to easily check if the enum contains the id so that I can decide if I can typecast or not? Or am I supposed to do like a switch statement and check for every single case?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

油饼 2025-02-02 17:42:55

或我应该喜欢开关语句并检查每种情况吗?

这可能是一个不错的解决方案。这样:

switch(id) {
    case char(TileType::WALL):
    case char(TileType::PASSAGE):
    case char(TileType::MONSTER):
    case char(TileType::CRYSTAL):
        return true;
    default:
        return false;
}

另一种选择是将所有有效值存储在数据结构(例如数组)中:

constexpr std::array valid {
    char(TileType::WALL),
    char(TileType::PASSAGE),
    char(TileType::MONSTER),
    char(TileType::CRYSTAL),
};

使用此类数据结构,您可以检查这样的有效性:

return std::ranges::find(valid, id) != valid.end();

编译器倾向于更好地优化开关。


无论哪种情况,使用元编程生成开关 /数组都可能是有用的。

Or am I supposed to do like a switch statement and check for every single case?

This is probably a decent solution. Like this:

switch(id) {
    case char(TileType::WALL):
    case char(TileType::PASSAGE):
    case char(TileType::MONSTER):
    case char(TileType::CRYSTAL):
        return true;
    default:
        return false;
}

Another alternative is to store all valid values in a data structure such as an array:

constexpr std::array valid {
    char(TileType::WALL),
    char(TileType::PASSAGE),
    char(TileType::MONSTER),
    char(TileType::CRYSTAL),
};

With such data structure, you can check validity like this:

return std::ranges::find(valid, id) != valid.end();

Compilers tend to be better at optimising the switch.


In either case, it may be useful to use meta-programming to generate the switch / the array.

倾城花音 2025-02-02 17:42:55

没有标准方法可以做到这一点。一种方法是使用第三方图书馆,例如 magic_enum ,这可能仍然对枚举范围有限制。

enum class TileType
{
    WALL= 'W',
    PASSAGE= 'P',
    MONSTER = 'M',
    CRYSTAL= 'C',
};

bool contains = magic_enum::enum_contains<TileType>('A');

demo

There is no standard way to do this. One way is to use a third-party library like magic_enum, which may still have limitations on the enum's range.

enum class TileType
{
    WALL= 'W',
    PASSAGE= 'P',
    MONSTER = 'M',
    CRYSTAL= 'C',
};

bool contains = magic_enum::enum_contains<TileType>('A');

Demo

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文