从底层类型安全地转换枚举类

Posted

技术标签:

【中文标题】从底层类型安全地转换枚举类【英文标题】: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 库可以用来有效地实现这一点 【参考方案1】:

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

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

【讨论】:

以上是关于从底层类型安全地转换枚举类的主要内容,如果未能解决你的问题,请参考以下文章

我java里的枚举不懂...

C#如何将枚举类(enum)型转换成字符(string)类型

Kotlin学习之枚举类

深度分析Java的枚举类型—-枚举的线程安全性及序列化问题

java中的枚举类

C#如何将枚举类(enum)型转换成字符(string)类型