Question about explicit template instantiation

Jarrett Billingsley kb3ctd2 at yahoo.com
Sun Feb 10 08:23:54 PST 2008


"Edward Diener" <eddielee_no_spam_here at tropicsoft.com> wrote in message 
news:foleie$67q$1 at digitalmars.com...
>I am working my way throught the pdf documentation ( 1.0 ) regarding 
>templates in D and in the topic about explicit template instantiation and I 
>came across the lines below, which have me stumped:
>
> ----------------------------------------------------------------
>
> A template instantiation can be aliased:
> template TFoo(T) { alias T* t; }
> alias TFoo!(int) abc;
> abc.t x; // declare x to be of type int*
> Multiple instantiations of a TemplateDeclaration with the same 
> TemplateArgumentList, before
> implicit conversions, all will refer to the same instantiation. For 
> example:
> template TFoo(T) { T f; }
> alias TFoo!(int) a;
> alias TFoo!(int) b;
> ...
>
> a.f = 3;
> assert(b.f == 3); // a and b refer to the same instance of TFoo
> This is true even if the TemplateInstances are done in different modules.
>
> ----------------------------------------------------------------
>
> My confusion with the above is that an alias, when referring to a type, is 
> the equivalent of a C++ typedef AFAICS. So 'a' and 'b' above are types ( 
> because the instantiated template is a type ) and then I see the 'a.f=3' 
> line followed by the 'assert(b.f == 3)' line and I can not understand how 
> a type can be used in either expression.

Aliases are a superset of the C/C++ typedef.  An alias is much more general, 
allowing you to not only rename types, but more generally, create a new 
symbol (name) that refers to another symbol.  This way, you can alias types, 
template instantiations, functions, methods, modules, etc. etc.

What's happening here is that TFoo is not a type, and an instance of TFoo is 
not a type either.  TFoo, when instantiated, is more like a namespace.  It 
has a single variable, f.  This is not a field or anything, it's just a 
variable.  When you instantiate TFoo with a type, you basically declare a 
global variable TFoo!(T).f.  So:

template TFoo(T)
{
    T f;
}

void foo()
{
    alias TFoo!(int) a;
    a.f++;
    Stdout.formatln("{}", a.f);
}

void main()
{
    foo();
    foo();
}

prints 1 and 2.  Notice that even though 'a' was aliased inside foo(), it's 
kind of like a static variable.

Contrast this with mixins, where the declarations are inserted at the 
instantiation location:

void foo()
{
    mixin TFoo!(int) a;
    a.f++;
    Stdout.formatln("{}", a.f);
}

This prints 1 and 1, since a.f is now basically a local variable.

> I am also assuming that the line beginning with "Multiple instantiations 
> of a..." only mean that the 'a' and 'b' refer to the same type, but 
> perhaps I have missed something in this explanation.

a and b refer to the same *symbol*, yes.  But instantiations of TFoo are not 
types. 





More information about the Digitalmars-d mailing list