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