【问题标题】:C++ enum class - initialization from underlying_typeC++ 枚举类 - 从底层类型初始化
【发布时间】:2014-08-02 18:29:04
【问题描述】:

我想在 C++11 中从其底层类型初始化一个强类型枚举,这是我从序列化流中读取的一个值,我必须检查它的数字范围是否正确。

类似:

enum class MyEnum {
    FOO, BAR
};

MyEnum test = static_cast<MyEnum>(1);

这按预期工作,但问题是:

MyEnum test2 = static_cast<MyEnum>(42);

也可以工作,并且不会显示错误。据我所知,枚举类也没有任何关于如何检查输入是否有效的边界概念或其他指标。在“旧式”枚举中,我们会包含一个 MIN 和 MAX 值并与它们进行比较,但是将这些值添加到强类型枚举中会再次向该类型添加无效值,从而破坏其用途。

如果值超出范围,我可以如何检查边界或强制出错?

更新

我刚刚尝试了 std::numeric_limits,但这也不适用于枚举类:

cout << static_cast<unsigned int>(numeric_limits<MyEnum>::min()) << endl;
cout << static_cast<unsigned int>(numeric_limits<MyEnum>::max()) << endl;

都返回 0。

【问题讨论】:

  • 如果你这样做 enum class MyEnum: unsigned int { FOO = 1, BAR = 2 }; 如果你再尝试 MyEnum test2 = static_cast&lt;MyEnum&gt;(42); 会发生什么?
  • 行为(在 gcc 4.6.2 上)与 unsigned int 相同。我可以使用“cout (test);”输出枚举并得到 42,所以它只是分配而没有任何检查。
  • 不幸的是枚举类不支持用户定义的方法或构造函数。所以我能想象的最干净的东西是一个检查值并返回枚举的独立方法:MyEnum MyEnumFromValue(int v) {...}
  • 枚举的基础类型是int。就 C++ 而言,int 范围内的任何值都是有效的。如果你想要一个有限的检查范围,那么你必须将它作为一个类类型来实现。

标签: c++ c++11 enums


【解决方案1】:

目前没有办法提取枚举的最小或最大枚举数,但http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3815.html 提出了足够的新类型特征来实现可以做到这一点的库。反射小组很感兴趣,但要求作者回来提出一个更清楚地推广到其他反射特征的提案。我相信http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4027.pdf 是这种概括的结果,它将在下周的会议上得到讨论。

【讨论】:

  • 谢谢,对于“当前不可能”的情况,这是一个很好的答案。这些文件确实很有趣,让我们看看何时/是否可用。
【解决方案2】:

std::numeric_limits 返回枚举的最大可能值(取决于数据类型),而不是现有的最大枚举值。

例子:

enum class MyType : uint8_t
{
    eType1    = 0,
    eType2    = 1,
    COUNT,
    MAXVAL    = std::numeric_limits<decltype(COUNT)>::max()
};

MAXVAL = 255

enum class MyType
{
    eType1    = 0,
    eType2    = 1,
    COUNT,
    MAXVAL    = std::numeric_limits<decltype(COUNT)>::max()
};

MAXVAL = 2147483647

【讨论】:

  • 无论您的答案是否正常,最好通过添加一些描述来改进它。请关注link了解如何操作。
猜你喜欢
  • 1970-01-01
  • 2010-11-10
  • 2021-01-23
  • 2017-10-27
  • 2011-10-21
  • 2020-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多