Template mixin problem with EnumMembers

Adam Ruppe destructionator at gmail.com
Sat Oct 2 22:24:56 UTC 2021


On Saturday, 2 October 2021 at 22:07:23 UTC, Ferhat Kurtulmuş 
wrote:
> The below code works as expected on https://run.dlang.io/, but 
> not on my computer. And I don't know why?

You used .stringof. That's undefined behavior. Never use 
stringof. (except for debugging writes)

Now, I'd actually probably do this entirely differently... just 
using opDispatch.

```
class Options{
     public:

     enum StringOption {
         OUT_FILE_NAME,
         RPT_FILE_NAME,
         MAP_FILE_NAME
     }

     static template opDispatch(string name) 
if(__traits(hasMember, StringOption, name)) {
         alias opDispatch = __traits(getMember, StringOption, 
name);
     }
}
```

and done. (even that `if` template constraint isn't really 
necessary and im usally anti-those too, but here it kinda makes 
sense. in theory. in practice it makes zero difference, but in 
theory, if the dmd regression that broke these error messages 
ever actually gets fixed, this would lead to better error 
messages this way. but anyway moving on)


That opDispatch just creates the aliases on-demand. You can't 
reflect over them directly if you wanted to - you'd still have to 
check enum members of Options.StringOption, which means things 
like std.conv.to won't pick it up, but it would work in normal 
use quite beautifully.



If you did want to do the ahead-of-time static foreach way, 
remember, never use .stringof. Find another way.

and tbh i'd ditch the std.traits thing too, it just complicates 
things. Use the language feature allMembers directly and it 
simplifies to this:

```
     mixin template StrOptAliases()
     {
         static foreach(name; __traits(allMembers, StringOption))
             mixin("alias " ~ name ~ " = " ~ " __traits(getMember, 
StringOption, name);");
     }
```

Notice that the ONLY thing outside the quotes to the mixin is the 
name. Everything else is inside. That's often the solution to 
follow my "never use stringof" advice - just leave things inside 
the quotes. String interpolation / concat is actually very rarely 
needed to build mixins. New declaration names are the main 
exception. But most everything else can just be referenced 
directly and it leads to code that is both less buggy and easier 
to read.

And, of course, it doesn't rely on random underspecified 
.stringof behavior that the compiler can change randomly in any 
release which is just the cherry on top.


More information about the Digitalmars-d-learn mailing list