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