Let's say we have an enumerated type E
.
enum class E : underlying_type_of_E {
v1 = uE1,
v2 = uE2,
//...
vN = uEN
};
typedef typename std::underlying_type<E>::type uE;
In general, not all values of uE
are valid values of E
, because we can choose the relationship between them. Is there a general way of creating random, valid (named in definition, not assignable), values of E?
This, for example would not work:
std::mt19937 m;
std::uniform_int_distribution<uE> randomUE(0, std::numeric_limits<uE>::max());
E e = static_cast<E>( randomUE(m) );
because:
Given that all of the enumerated values are known at compile-time, I cannot imagine a reason why would this be in any way dangerous, or error-prone.
As for a context of why I want such a thing - I'm working on a genetic algorithm that uses templated gene storage. For now, I use enums as chromosomes and store them in std::vector<bool>
which is converted into std::vector<enumT>
on demand. The problem with this approach is mutation that flips random bits with given probability. That can cause problems, as it can produce invalid chromosomes that are unnamed enum values.
You can do this if you're prepared to use a preprocessor macro to create both the enum
type and some meta-data about it, but it's a minor hassle:
Invoke a variadic macro:
ENUM(E,
v1 = uE1,
v2 = uE2,
// ...
vN = uEN);
Create a templated class Incrementing
where successive variables are initialised by an incrementing static
member by default, but can be assigned to from whatever your underlying type is (e.g. int
).
static Incrementing<E, Underlying> __VA_ARGS__; \
Use the values above to initialise a array with the Incrementing
values (which need an operator Underlying() const
member).
static const Underlying values[] = { __VA_ARGS__ }; \
The values[]
array then contains the named enumeration values....
There's a total overkill version of this concept I wrote years ago here, but I'd recommend just starting from scratch given your simple requirements.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With