如何检查基础类型值是否为枚举值?

时间:2018-11-07 13:38:43

标签: c++ enums

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

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

3 个答案:

答案 0 :(得分:8)

目前无法执行此操作。

有一些反射建议可以将其放入和/或中,使您可以对枚举中的枚举值进行迭代(在编译时,进而在运行时)。使用该检查相对容易。

有时候人们经常使用宏进行手动枚举反射。

答案 1 :(得分:7)

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

根据上下文,我倾向于要么构建一个静态的std::unordered_set(并对其进行查找),要么拥有一个在switch中列出我所有枚举器的函数(并返回{{1} }(如果输入中的任何一个都不匹配),或者只是不打扰,而是在某处进行文档说明,将未枚举的false值传递给我的函数将被视为不道德的行为,并且具有未指定的行为。

最终,所有这些源于以下事实:枚举应该在更广泛的完全有效状态中列出“方便命名的公用值”,而不是仅由完全约束的常数集组成的类型。我们几乎所有的滥用枚举。

答案 2 :(得分:2)

尽管该标准尚未允许您进行自省,但是您可以使用一个小的解决方法,可以使用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))