【问题标题】:How should I check whether an underlying-type value is an enumerated value?我应该如何检查基础类型值是否是枚举值?
【发布时间】:2019-04-10 22:46:26
【问题描述】:

I 成为某种整数类型。现在假设我有一个enum class my_enum_class : I,其值可能不是连续的。现在我得到了一些I 值。如何检查它是否是my_enum_class中枚举的值?

a similar question 的答案(对于 C 语言)假设值是连续的,并且可以添加一个“虚拟”上限值,并检查 0 和该值之间的范围;这与我的情况无关。还有其他方法吗?

【问题讨论】:

  • 所以实际上是取某个整数类型的值并查看它是否在某个其他整数类型的范围内。基本上不是关于枚举。也许codereview.stackexchange.com/q/5515/2503
  • 您将遇到的最大问题是枚举中提供的值内的任何值都是有效的,即使它实际上并未映射到枚举值。这需要我们没有的反射,因此您必须自己构建地图。
  • @einpoklum - 您的编辑不会影响我的评论。就s/int/I/
  • @NathanOliver:所以你的答案是“目前还没有,但可能在未来有委员会讨论的静态反射”?

标签: c++ enums


【解决方案1】:

虽然该标准还不允许您进行自省,但您可以使用一个小的解决方法,它可能会通过 ADL 得到改进。致谢this older answer

namespace sparse {
  template<typename E>
  constexpr bool in_(std::underlying_type_t<E> i) { return false; }

  template<typename E, E value, E...values>
  constexpr bool in_(std::underlying_type_t<E> e) {
    return static_cast<E>(e) == value || in_<E, values...>(e);
  }
}

这样使用:

enum class my_enum: int { a=3, b=4 };

template<>
constexpr auto sparse::in<my_enum> =
     in_<my_enum, my_enum::a, my_enum::b>;

static_assert(sparse::in<my_enum>(3));
static_assert(sparse::in<my_enum>(4));
static_assert(!sparse::in<my_enum>(5))

【讨论】:

  • 虽然这很有用,但它需要重复所有值的枚举特定代码。
  • 是的。而且我认为,由于所要求的行为超出了标准,这是一个合理的要求。
  • 很公平,你把我带到了那里...... +1。
  • 1.为什么需要in() 中的默认实现? 2.不应该用std::underlying_type_t&lt;E&gt;代替int吗?
  • 是的,我应该使用underlying_type。我会适应的。另外,我猜“真实”枚举不需要默认的in_
【解决方案2】:

没有内置的方法可以做到这一点。所有Is 都是my_enum_class 的“有效”值,因此您无法对基础类型执行任何操作。至于根据枚举器列表验证Is,如果没有反射,根本就没有办法做到这一点。

根据上下文,我倾向于构建一个静态的std::unordered_set(并对其进行查找),或者有一个函数在switch 中列出我的所有枚举数(如果输入不匹配则返回false其中),或者只是不打扰,而是在某处记录将未枚举的my_enum_class 值传递给我的函数将被视为顽皮的诡计并且具有未指定的行为。

归根结底,这一切都源于这样一个事实,即枚举应该在更广泛的完全有效状态中列出“常见的方便命名的值”,而不是仅由一组完全受约束的常量组成的类型。我们几乎都滥用枚举。

【讨论】:

  • 其实我是想用它来增强this数值范围访问机制,从而更好地支持非连续枚举。
【解决方案3】:

目前没有办法做到这一点。

有一些反射提案可能会使其成为 和/或,让您迭代(在编译时,因此运行时)枚举中的枚举值。使用该检查将相对容易。

有时人们会手动进行枚举反射,通常使用宏。

【讨论】:

  • Reflection 最早是 23。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-02-12
  • 1970-01-01
  • 1970-01-01
  • 2021-05-12
  • 1970-01-01
相关资源
最近更新 更多