Очевидна річ - анотувати свій перелік:
#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) {
if (std::binary_search(first, last, v)) return T(v);
} else if (std::find(first, last, v) != last) {
return T(v);
}
throw "exception";
}
enum e {
x = 1,
y = 4,
z = 10,
};
template<>
struct enum_traits<e> {
static const e enumerators[];
static const bool sorted = true;
};
const e enum_traits<e>::enumerators[] = {x, y, z};
int main() {
e good = check<e>(1);
e bad = check<e>(2);
}
Вам потрібно, щоб масив був в курсі e
, що неприємно, якщо ви не автор e
. Як каже Сьоерд, її, мабуть, можна автоматизувати за допомогою будь-якої гідної системи збірки.
У будь-якому випадку, ви проти 7,2 / 6:
Для перелічення, де emin є найменшим перелічувачем, а emax є найбільшим, значення перерахування - це значення базового типу в діапазоні від bmin до bmax, де bmin та bmax - відповідно, найменше та найбільше значення найменшого бітове поле, яке може зберігати emin та emax. Можна визначити перелік, що має значення, не визначені жодним із його перерахувачів.
Отже, якщо ви не є автором e
, ви можете або не мати гарантії того, що дійсні значення e
насправді відображаються у його визначенні.
enum e{x = 10000};
чи в цьому випадку9999
потрапляє в діапазонenum
?