need help with CTFE

anonymous via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Thu Mar 26 10:30:39 PDT 2015


On Thursday, 26 March 2015 at 16:19:17 UTC, Dmitri Makarov wrote:
> When I compile version DOES_NOT_WORK, I get the following error:
> c/tool.d(13): Error: variable name cannot be read at compile 
> time
> c/tool.d(13):        while looking for match for 
> hasMember!(Tool, name)
>
> However, the other version ('else' case) compiles, runs, and 
> outputs (as expected):
> this is a screwdriver.
> unknown tool transmogrifier.
>
> What's the fundamental difference that makes the variable 
> 'name' readable in one version and unreadable in another?
>
> Should the version DOES_NOT_WORK not be compilable in principle 
> or is it only a limitation of the current CTFE implementation 
> in the front-end?

In DOES_NOT_WORK you're trying to pass `name` in a template value 
parameter. You cannot do that, because `name` is a "dynamic 
value" but you can only pass a "static value" there. (There may 
be better terms than dynamic/static value.)

You may think: But it all happens in CTFE, so all values are 
"compile time values" or "static values", aren't they?

They aren't. The semantics during CTFE are the same as for run 
time. `name` is still a dynamic value. If it doesn't fly for run 
time execution, it doesn't fly in CTFE.

To solve the problem at hand, here's one solution that's similar 
to what you tried:

     string generate()
     {
         import std.traits : isCallable;
         foreach(memberName; __traits(allMembers, Tool))
         {
             if(memberName == name)
             {
                 alias M = typeof(mixin("this." ~ memberName));
                 static if(isCallable!M)
                 {
                     return `writeln("this is a ` ~
                         mixin("this." ~ memberName ~ "()") ~ 
`.");`;
                 }
             }
         }
         return `writeln("unknown tool ` ~ name ~ `.");`;
     }

The foreach is (implicitly) a 'static' one, because 
__traits(allMembers, ...) results in a static/type/expression 
tuple (I don't know what's the best name to set it apart from 
other kinds of tuples).

That means, `memberName` is a static value. And so it can be used 
in mixin, whereas `name` cannot be used there.


More information about the Digitalmars-d-learn mailing list