On Thursday, 13 February 2014 at 02:30:47 UTC, Frustrated wrote:
On Thursday, 13 February 2014 at 02:14:02 UTC, Jakob Ovrum
wrote:
On Thursday, 13 February 2014 at 02:02:38 UTC, Anton wrote:
I'm confused about how to use random.uniform to select a
member of an enum.
Say I have an enum like
enum Animals
{
cat = 0,
dog = 1,
chimpanzee = 2
}
I want to select a random animal. So far I've been trying to
do uniform(Animals), but every time I try to compile that, I
get a "does not match any function template declaration"
error.
Am I misunderstanding how this function is meant to be used?
The problem with using `uniform` for enums is that not all
enums are sequential without holes, which would make the
`uniform` implementation quite non-trivial if it were to try
to handle enums generically.
If you know your enum is sequential and doesn't have any
holes, assume responsibility for that fact with a cast:
---
enum Animals
{
cat = 0,
dog = 1,
chimpanzee = 2
}
void main()
{
import std.random, std.stdio;
foreach(immutable _; 0 .. 10)
writeln(cast(Animals)uniform!"[]"(Animals.min, Animals.max));
}
---
Could you not simply select one at random by "name"? Even though
the values of the enum may not be sequential the keys are.
import std.random, std.stdio, std.traits;
enum Animals
{
dog = "dog",
cat = "cat",
fox = "fox",
cow = "cow",
}
void main()
{
auto animals = [EnumMembers!Animals];
auto rnd = uniform!"[)"(0, animals.length);
writeln(animals[rnd]);
}
You have to wrap the EnumMembers template in an array, because
tuples can only be sliced at compile-time, and uniform doesn't
work at compile time.