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
 }
}

Reply via email to