让I
为某种整数类型。现在假设我有一个enum class my_enum_class : I
,其值可能不是连续的。现在,我得到了一些I
值。如何检查它是否是my_enum_class
中枚举的值?
对a similar question(对于C语言)的回答是假设值是连续的,并且可以添加一个“虚拟”上限值,并检查0到该值之间的范围。这与我的情况无关。还有另一种方法吗?
答案 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))