Das Offensichtliche ist, Ihre Aufzählung zu kommentieren:
// 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,
};
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[] = {x, y, z};
// usage
int main() {
e good = check<e>(1);
e bad = check<e>(2);
}
Sie müssen das Array auf dem neuesten Stand halten e
, was ein Ärgernis ist, wenn Sie nicht der Autor von sind e
. Wie Sjoerd sagt, kann es wahrscheinlich mit jedem anständigen Build-System automatisiert werden.
In jedem Fall haben Sie es mit 7.2 / 6 zu tun:
Bei einer Aufzählung, bei der emin der kleinste Aufzähler und emax der größte ist, sind die Werte der Aufzählung die Werte des zugrunde liegenden Typs im Bereich von bmin bis bmax, wobei bmin und bmax die kleinsten und größten Werte des kleinsten sind Bitfeld, das Emin und Emax speichern kann. Es ist möglich, eine Aufzählung zu definieren, deren Werte von keinem ihrer Aufzähler definiert wurden.
Wenn Sie also nicht der Autor von sind e
, haben Sie möglicherweise eine Garantie dafür, dass gültige Werte von e
tatsächlich in der Definition von angezeigt werden .
enum e{x = 10000};
fällt in diesem Fall9999
in die Reichweite derenum
?