Cannot implicitly convert expression `true` of type `bool` to `Flag`

Ali Çehreli acehreli at yahoo.com
Thu Oct 15 21:33:32 UTC 2020


std.typecons.Flag and its friends Yes and No are so trivial that I copy 
them here (and reformat for my liking):

template Flag(string name) {
   enum Flag : bool {
     no = false, yes = true
   }
}

struct Yes {
   template opDispatch(string name) {
     enum opDispatch = Flag!name.yes;
   }
}

struct No {
   template opDispatch(string name) {
     enum opDispatch = Flag!name.no;
   }
}

void main() {
   auto a = Flag!"foo".no;     // Fine
   auto b = No.foo;            // Fine

   // Error: cannot implicitly convert expression `true` of type `bool` 
to `Flag`:
   auto c = Flag!"foo"(true);
}

I think that is a wrong limitation because clearly I am being "explicit" 
there with a bool value. (I understand the issue but it exposes a 
limitation of the implementation.) I have to use the ternary operator 
e.g. after parsing a bool from program arguments:

   bool someFlag;
   // ...
   foo(someFlag ? Yes.someFlag : No.someFlag);

Spoiler alert: I will show the following function template during my 
DConf Online presentation as a workaround (or "solution"):

auto asFlag(alias variable)() {
   enum name = variable.stringof;
   enum expr = "return variable ? Yes." ~ name ~ " : No." ~ name ~ ";";
   mixin (expr);
}

That allows the following cleaner and "explicit" syntax:

   bool someFlag;
   // ...
   foo(asFlag!someFlag);

(I actually called it flagFromBool in existing code.)

However:

1) I think the standard library should already have something like that 
to remove the need for that ternary operator.

2) (This feels like something that must have been requested already.) 
While we're on the topic of removing unnecessary limitations, it would 
be nice to be able to use "not necessarily quoted string template 
arguments" just like opDispatch empowers us with.

void foo(Foo!"myFlag" myFlag) {  // <-- Ugly
}

void foo(Foo!myFlag myFlag) {    // <-- Better
}

Maybe there would be a parsing issue with the syntax but then opDispatch 
seems to be happy with it. Perhaps we should add opDispatch to 
templates? (Because I tried but failed to achieve the "better" syntax 
above with opDispatch inside (a struct inside) a template.)

If it requires a special template parameter syntax we can always abuse 
'static' further: :o)

template Flag(static string name) {
   // ...
}

Ali


More information about the Digitalmars-d mailing list