CTFE calling a template: Error: expression ... is not a valid template value argument

Jens Mueller jens.k.mueller at gmx.de
Fri Sep 21 03:21:22 PDT 2012


Jens Mueller wrote:
> Jonathan M Davis wrote:
> > On Friday, September 21, 2012 00:11:51 Jens Mueller wrote:
> > > I thought foo is interpreted at compile time.
> > > There seems to be a subtle difference I'm not getting.
> > > Because you can do the factorial using CTFE even though you have
> > > recursion. I.e. there you have a call to the function itself. I.e. it
> > > can be compiled because you just insert a call to the function. But for
> > > a template you cannot issue something like call for instantiation.
> > > Have to think more about it. But your answer helps a lot. Pushes me in
> > > the right direction.
> > 
> > Okay. Straight up recursion works. So, with this code
> > 
> > int func(int value)
> > {
> >  if(value < 10)
> >  return func(value + 1);
> >  return value;
> > }
> > 
> > enum var = func(5);
> > 
> > var would be 10. The problem is that you're trying to pass the result of a 
> > recursive call as a template argument. As far as a function's behavior goes, 
> > it's identical regardless of whether it's run at compile time or runtime (save 
> > that __ctfe is true at compile time but not runtime). To quote the docs:
> > 
> > ------
> > Any func­tions that ex­e­cute at com­pile time must also be ex­e­cutable at 
> > run time. The com­pile time eval­u­a­tion of a func­tion does the equiv­a­lent 
> > of run­ning the func­tion at run time. This means that the se­man­tics of a 
> > func­tion can­not de­pend on com­pile time val­ues of the func­tion. For ex­
> > am­ple:
> > 
> > int foo(char[] s) {
> >  return mixin(s);
> > }
> > 
> > const int x = foo("1");
> > 
> > is il­le­gal, be­cause the run­time code for foo() can­not be gen­er­ated. A 
> > func­tion tem­plate would be the ap­pro­pri­ate method to im­ple­ment this 
> > sort of thing.
> > ------
> 
> Is it also illegal to do
> 
> int foo(char[] s) {
>   if (__ctfe)
>     return mixin(s);
>   else
>     return ""; // or assert(false)
> }
> 
> ?
> 
> Because this is executable at run time.

Just read the docs again. And __ctfe is used to exclude running code at
runtime. It seems it really is a variable that is false at runtime. I
thought it more a value known at compile time. But then you would write
static if anyway.

Somehow I find these restrictions unnecessary. I believe they can be
solved. Then you could combine CTFE with all other compile-time
mechanisms. But this needs more time to think about. Currently I will
try to work around this. Let's see ...

Jens


More information about the Digitalmars-d mailing list