Generic way to cast int to enum in C++

前端 未结 8 2121
[愿得一人]
[愿得一人] 2020-12-04 11:26

Is there a generic way to cast int to enum in C++?

If int falls in range of an enum it should return

8条回答
  •  青春惊慌失措
    2020-12-04 11:44

    The obvious thing is to annotate your enum:

    // generic code
    #include 
    
    template 
    struct enum_traits {};
    
    template
    T *endof(T (&ra)[N]) {
        return ra + N;
    }
    
    template
    T check(ValType v) {
        typedef enum_traits traits;
        const T *first = traits::enumerators;
        const T *last = endof(traits::enumerators);
        if (traits::sorted) { // probably premature optimization
            if (std::binary_search(first, last, v)) return T(v);
        } else if (std::find(first, last, v) != last) {
            return T(v);
        }
        throw "exception";
    }
    
    // "enhanced" definition of enum
    enum e {
        x = 1,
        y = 4,
        z = 10,
    };
    
    template<>
    struct enum_traits {
        static const e enumerators[];
        static const bool sorted = true;
    };
    // must appear in only one TU,
    // so if the above is in a header then it will need the array size
    const e enum_traits::enumerators[] = {x, y, z};
    
    // usage
    int main() {
        e good = check(1);
        e bad = check(2);
    }
    

    You need the array to be kept up to date with e, which is a nuisance if you're not the author of e. As Sjoerd says, it can probably be automated with any decent build system.

    In any case, you're up against 7.2/6:

    For an enumeration where emin is the smallest enumerator and emax is the largest, the values of the enumeration are the values of the underlying type in the range bmin to bmax, where bmin and bmax are, respectively, the smallest and largest values of the smallest bit-field that can store emin and emax. It is possible to define an enumeration that has values not defined by any of its enumerators.

    So if you aren't the author of e, you may or may not have a guarantee that valid values of e actually appear in its definition.

提交回复
热议问题