【问题标题】:Safely convert enum class from underlying type从底层类型安全地转换枚举类
【发布时间】:2020-01-04 00:51:01
【问题描述】:

假设我有一个像这样的强类型枚举类型:

enum class message : int {
    JOIN = 0,
    LEAVE = 4,
    SPAWN = 1,
}

而且我需要安全地(在这种情况下安全地意味着丢弃无效的变体)将它从它的基础类型 (int) 转换。

为此,我有一个函数可以帮我转换它:

std::optional<message> get_message(int num) {
    return num == (int)message::JOIN || num == (int)message::LEAVE || num == (int)message::SPAWN ? (message)num : {};
}

这行得通,但是写起来很长并且容易出错,尤其是对于具有大量变体的枚举。

有没有办法在 C++17 中自动化这个过程?

【问题讨论】:

  • 任何int 值都是message 的有效值。如果您想检查 value 是否是预定义的常量之一,那么是的,您将需要执行手动映射。可以用宏来简化。
  • 只需 std::set&lt;message&gt; 即可。排序的constexpr 数组也可以很好地用于二分搜索。
  • @FrançoisAndrieux std:set 如何帮助过滤掉未定义的值?
  • 如果枚举很短,则可以使用“或”表达式。如果最大值不超过 31 (63),则测试 (1 &lt;&lt; num) &amp; mask,其中 mask 结合了所有允许的值。在其他情况下,请使用地图。
  • 这是 Neargye/magic_enum 的 magic_enum::enum_cast: github.com/Neargye/magic_enum ,虽然这不是很有效(它正在做一个字符串比较:godbolt.org/z/sItmZb )。不过,也许这个 magic_enum 库可以用来有效地实现这一点

标签: c++ enums integer c++17


【解决方案1】:

谈到底层类型,我们注意到这个类只是使用另一种类型作为模型来获取一个类型,但它不会在这些类型之间转换值或对象。

作为简化功能的一个选项,您可以通过在枚举中迭代来工作,或者正如其他人之前所说的使用某种类型的容器,通过迭代相同的枚举作为此处的示例:How can I iterate over an enum? 以及有关枚举的更多信息以防万一:https://docs.microsoft.com/en-us/cpp/cpp/enumerations-cpp?view=vs-2019

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-11
    • 1970-01-01
    相关资源
    最近更新 更多