0

While looking for a generic way to perform an enum cast, I stumbled across an interesting solution posted here. In order to strengthen the underlying enum data types, I tried to replace the conventional enum with a C++11 enum class as follows:

// generic code
#include <algorithm>

template <typename T>
struct enum_traits {};

template<typename T, size_t N>
T *endof(T(&ra)[N]) {
    return ra + N;
}

template<typename T, typename ValType>
T check(ValType v) {
    typedef enum_traits<T> 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,
};
*/

// new C++11 enum class
enum class e : int {
    x = 1,
    y = 4,
    z = 10,
};

template<>
struct enum_traits<e> {
    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<e>::enumerators[] = { e::x, e::y, e::z };

// usage
int main() {
    e good = check<e>(1);
    e bad = check<e>(2);
}

However, this leads to a crash during the compilation process (error C1001: An internal error has occurred in the compiler.). I can't seem to figure out what's causing this, but my guess is that the std::find() and/or std::binary_search() functions are having problems dealing with the enum class. Has someone experienced a similar issue yet?

Community
  • 1
  • 1
Aurora
  • 1,334
  • 8
  • 21
  • Confirmed: http://rextester.com/live/GWMY82375 – Mooing Duck Mar 11 '15 at 22:36
  • Well, GCC thinks code is buggy because in binary search there is no match for op< (const e, const int) – Severin Pappadeux Mar 11 '15 at 22:46
  • 1
    This code is broken anyway because`binary_search` requires either a custom comparator or something that supports `<`, and scoped enums can't be compared with `int`s. (The `find` call has similar issues, this time for `==`.) – T.C. Mar 11 '15 at 22:46

0 Answers0