从底层类型安全地转换枚举类
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<message>
即可。排序的constexpr
数组也可以很好地用于二分搜索。
@FrançoisAndrieux std:set
如何帮助过滤掉未定义的值?
如果枚举很短,则可以使用“或”表达式。如果最大值不超过 31 (63),则测试 (1 << num) & 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
【讨论】:
以上是关于从底层类型安全地转换枚举类的主要内容,如果未能解决你的问题,请参考以下文章