On Monday, 16 July 2012 at 17:35:33 UTC, Tommi wrote:
According to the docs, std.conv.to uses cast operator under the
hood, and since the following works:
enum MyEnumType {a}
auto val = cast(MyEnumType) 42;
...it seems natural that to!MyEnumType(42) should work as well.
But currently it gives error:
template instance std.conv.to!(MyEnumType).to!(int) error
instantiating
You can convert a enum to an int, but not the other way around.
Enums are not a 'range', rather a bunch of const values with a
tag stating it's type. Let's check against your example with a
little modification.
enum MyEnumType { none, a = 100 } //so far so good
int i = MyEnumType.a; //success
MyEnumType x = MyEnumType.a; //success, so far so good.
MyEnumType y = cast(MyEnumType) 42; //Error: wtf is 42 anyways?
MyEnumType z = cast(MyEnumType) 100; //Error: an int is not an
enum! (Even if it's a valid match)
// although...
assert(x == 100); //enum converts to int.
assert(x == i);
assert(x == MyenumType.a);
These may seem like strict rules, and there may be cases where a
combination of flags are valid, but setting an invalid state in a
fixed range of 'const' values doesn't work. I suppose the same
thing could be compared to an enum being a set of car keys, and
every proper enum value is a car key, but when you give something
that's not a car key (Say, a brick) then it isn't going to fit,
not matter how hard you try to force it into the key hole.
Enums with fixed values (and a number of them) are good for
flags and limited ID types. It also allows you as TDPL gives an
example where you can make a statement that handles ALL possible
values.
with(MyEnumType) {
final switch(x) { //of type MyEnumType. ALL possibilities MUST
be present
case none: //something
case a: //something else
//no possible 42 value here, no matter how hard you try;
//and since we handle all cases, default should not be used
}
}