2 Templates Issues (possibly bugs)

John Kiro johnkirollos at yahoo.com
Tue Oct 9 10:47:29 PDT 2007


Thanks again BCS,

It's clearer now. I found the part in the documentation equivalent to what you explained:
In Templates page: "Template Instantances are always performed in the scope of where the TemplateDeclaration is declared..."

And in Template Mixins page: "Unlike a template instantiation, a template mixin's body is evaluated within the scope where the mixin appears, not where the template declaration is defined."

So although I instantiated the template inside the main() body, the instances (Which are variables in my case) were actually instantiated in the template scope (which is global), that's why initialization with non-constant was refused.

Using template mixins solves this problem. However, what I was trying to achieve is to have different variables based on the function alias passed as argument. I can't achieve this using template mixins as defining more than 1 mixin would try to create several variables having the same name, => compilation error. Anyway, I'll search for another method to achieve my aim.

I'll also check the writefln issue to see if there is indeed a bug.

And thanks for the last example.. interesting indeed!

Regards,
John

BCS Wrote:

> Reply to John,
> 
> > Thanks BCS,
> > 
> > I still have questions below..
> > 
> > BCS Wrote:
> > 
> >>> template Template1(T, alias Var, alias Func)
> >>> {
> >>> T abc = Func();		//OK.
> >>> T xyz = Var;		//#1 Error: non-constant expression i1
> >>> //Question 1: Why do I have this error?
> >>> }
> >>> The above error is issued in case I instantiate the template like
> >>> this
> >>> for ex:
> >>> Template1!(int, i1, Func1).abc = 3;
> >>> Or
> >>> Template1!(int, i1, Func1).xyz = 3;
> >> what is i1 in this case.
> >> 
> > i1 is defined inside main() like this:
> > int i1=900;
> 
> In that case the problem is that i1 is not a constant expression. A variable 
> declared inside of a template in many respects is like a global variable, 
> or a static variable in a struct. As such, if you declare it and initialize 
> it at the same time then the thing used to initialize it must be a constant. 
> In your case i1 isn't.
> 
> >> that is correct, referencing the variable var1 but not using it for
> >> anything has no effect and is disallowed.
> >> 
> > What I understand is that "Template2!(int,Func1,Func2).var1;" is
> > equivalent to
> > int var1 = TFunc1();
> > Isn't it? If so, then what's wrong with it?
> 
> In D a template is a scope. Everything inside of it is instanced once for 
> each set of arguments that the template is used with. As such Template!(int,Func1,Func2).var1 
> is just another variable. Ignoring the template stuff for a moment what you 
> get is approximately the same as this:
> 
> // At the location Template1 is defined
> int var1 = TFunk1(); 
> 
> ...
> 
> // At the location Template1 is used.
> var1;
> 
> If you want to plop down an instance of everything in the template in the 
> current scope, then you need to use a mixin.
> 
> >> The template you defined contains two global variables that are
> >> initialized with the return from two function that are passed in.
> >> 
> >> The two issues you mention may be related. What I think is happening
> >> is that the initializer for a variable must be a constant. Due to
> >> compile time function evaluation (CTFE) the trivial function you used
> >> get converted to there return values.
> >> 
> > Yes it seems to be so, but I don't see any restriction in the
> > documentation that the initialization must be with a constant.
> > 
> 
> I could be mistaken, but I think the only case where a con constant finalization 
> is allowed is for local variables in a function (this is related to the fact 
> that executable code is only allowed in a function). As noted above, the 
> declaration inside a template are effectively global and as such are not 
> inside a function, thus they need constants if they are initialized.
> 
> >> If I had to guess, I'd say that the "i1" from above is a non trivial
> >> function that can't be run through CTFE.
> >> 
> > I tried something: I referenced a global var inside Func2(), and I got
> > the error: "Error: cannot evaluate Func2() at compile time", thus
> > confirming your thoughts. But as I said, why isn't this allowed, is it
> > a template restriction? Where is it stated in the document?
> 
> see above.
> 
> > 
> > Strangely, adding a writefln() call inside Func2() doesn't cause any
> > error like this, although this call cannot be done in compile-time!
> > 
> 
> Unless something else is happening that is a bug. Did it actually compile 
> and run with that version? If it gave another error, then it might not have 
> gotten that far. Get everything else sorted out and if writefln still works, 
> then you have found a bug.
> 
> >> as noted above, the expression "Template2!(int,Func1,Func2).var1" is
> >> a symbol in all cases. it is actually a reference to a global
> >> variable declared in the template.
> >> 
> > This is not what I understand; what I know is that template definition
> > doesn't define any variables, it's same as class definition. No object
> > is defined until the class is instantiated.
> > 
> > A global var would be declared if I instantiate the template or use a
> > template mixin.
> >
> 
> I think I covered this above, but to be sure...
> 
> As you note, a template definition doesn't define any variables. However 
> when you uses a template (e.i. Template1(Type, Foo, Bar) ) then you have 
> defined the set of symbols described inside the template. If you then use 
> the template again with different arguments, then you define another set 
> of symbols. It is interesting to note that you can declare a template with 
> a non const variable in it and then reference the same variable from different 
> locations.
> 
> template T(char[] name)
> {
>    int i=0;
> }
> 
> void main()
> {
>   T!("hello").i = 5;
>   T!("world").i = 7;
>   T!("hello").i --;
>   T!("world").i ++;
> 
>   writef("%d, %d\n", T!("hello").i, T!("world").i); // should print "4, 8"
> }
> 
> It seems that you are thinking of template just slightly different than D 
> uses them. I'm guessing that this is coming from using template in some other 
> language (C++ perhaps?) that  has a slightly different take on them.
> 
> 
> 




More information about the Digitalmars-d mailing list