How to check if enum value is valid?

前端 未结 8 1584
一向
一向 2020-11-27 06:38

I am reading an enum value from a binary file and would like to check if the value is really part of the enum values. How can I do it?



        
8条回答
  •  攒了一身酷
    2020-11-27 07:16

    Yet another way to do it:

    #include 
    #include 
    #include 
    
    template
    struct enum_traits { static constexpr void* values = nullptr; };
    
    namespace detail
    {
    
    template
    constexpr bool is_value_of(int, void*) { return false; }
    
    template
    constexpr bool is_value_of(int v, U)
    {
        using std::begin; using std::end;
    
        return std::find_if(begin(enum_traits::values), end(enum_traits::values),
            [=](auto value){ return value == static_cast(v); }
        ) != end(enum_traits::values);
    }
    
    }
    
    template
    constexpr bool is_value_of(int v)
    { return detail::is_value_of(v, decltype(enum_traits::values) { }); }
    
    ////////////////////
    enum Abc { A = 4, B = 8, C = 12 };
    
    template<>
    struct enum_traits { static constexpr auto values = { A, B, C }; };
    decltype(enum_traits::values) enum_traits::values;
    
    enum class Def { D = 1, E = 3, F = 5 };
    
    int main()
    {
        std::cout << "Abc:";
        for(int i = 0; i < 10; ++i)
            if(is_value_of(i)) std::cout << " " << i;
        std::cout << std::endl;
    
        std::cout << "Def:";
        for(int i = 0; i < 10; ++i)
            if(is_value_of(i)) std::cout << " " << i;
        std::cout << std::endl;
    
        return 0;
    }
    

    The "ugly" part of this approach IMHO is having to define:

    decltype(enum_traits::values) enum_traits::values
    

    If you are not opposed to macros, you can wrap it inside a macro:

    #define REGISTER_ENUM_VALUES(name, ...) \
    template<> struct enum_traits { static constexpr auto values = { __VA_ARGS__ }; }; \
    decltype(enum_traits::values) enum_traits::values;
    

提交回复
热议问题