No we should not support enum types derived from strings

Adam D. Ruppe destructionator at gmail.com
Fri May 7 17:42:24 UTC 2021


On Friday, 7 May 2021 at 17:02:17 UTC, Paul Backus wrote:
> We can already *almost* express this in the language. This code 
> works:

eeeeh that's a compile time argument and it still isn't actually 
a string.

What I'm talking about is like in the normal function:

void test(string s) {
         writeln(s);
}

enum Test : string {
         a = "foo"
}

test(Test.a);


The conversion to string happens outside `test`. So caller 
instead of callee, whereas with a template - any template - the 
exact type is passed, what T:string is saying is that the callee 
*can* do the conversion if it wants to inside, but the compiler 
won't actually do it for you.

This is very useful in a lot of cases. Like if you do

void foo(T : SomeBase)(T t) {}

and pass foo(new Derived()), you can still see the whole Dervied 
type and thus do some reflection and such over it, with the 
compiler promising that it can be converted to SomeBase if you 
want to.

Of course, in this case, it is not really different than a 
template constraint. You could do

void foo(T)(T t) if(is(T : SomeBase)) {}

and get that same rejection behavior. But of course what's nice 
about specialization is you can then add an overload

void foo(T : SomeBase)(T t) {}
void foo(T : Derived)(T t) {}

And if you get like

class Derived : SomeBase {}
class OtherBranch : SomeBase{}

and call

foo(new Derived()); // goes to second overload as it is a more 
specific match
foo(new OtherBranch()); // goes to first overload as it is the 
best option available, but it still can see it is OtherBranch 
inside there, unlike a normal interface cast where you'd only 
have that detail at runtime.




More information about the Digitalmars-d mailing list