August 21, 2002
"anderson" <anderson@firestar.com.au> wrote in message news:ak04p5$t3u$1@digitaldaemon.com...
> That sounds more like a functional template then a class template. Parhaps
D
> needs that as well?

D does not have a distinction between class and function templates. An entire group of declarations of any kind can be within a template body, including classes, functions, variables, enums, nested templates, etc.


August 21, 2002
"Russ Lewis" <spamhole-2001-07-16@deming-os.org> wrote in message news:3D637991.FF91430E@deming-os.org...
> In the "Argument Deduction" section,  I don't understand the Bar(D, D : D[]) example.  Does this mean that you have only one template parameter, "D", and you have to specify it in 2 different ways?  If not, then what does it mean?

That defines, to use C++ terminology, a "partial specialization", and is equivalent to the C++:

    template<class D> int Bar<D, D[]>() { }

It means there are two arguments to the template, and to instantiate it you need to specify both. While this doesn't make a whole lot of sense by itself, it is to distinguish Bar(D,D[]) from another template Bar(D,E).


August 21, 2002
"anderson" <anderson@firestar.com.au> wrote in message news:ajvr5q$i69$1@digitaldaemon.com...
> Looks pretty complete for my needs (although I'm no template expert).
Simple
> yet powerful. Just a few questions.
>
> "
> template Foo(T);
>  in Foo(int); // T is deduced to be int
>  in Foo(char*); // T is deduced to be char*
> "
> I don't understand this where is the InstanceIdentifier? Or is this some
> type of overloaded function call?

I forgot to put in the InstanceIdentifier. Oops!

> I guess this is a stupid question, but will it support operator
overloading?

Sure.


August 21, 2002
"Mac Reiter" <Mac_member@pathlink.com> wrote in message news:ak09pv$1b4k$1@digitaldaemon.com...
> 1. I would prefer something other than 'in' for 'instantiation'.  I
realize that
> 'instance' might be annoying to type, but I will never be able to look at
'in'
> and see anything except 'the opposite of out'.  I could go with 'inst',
which
> contains enough of the word to suggest 'instance' to me.  (I have similar problems with the standard C++ STL notation of InIt for an Input
Iterator -- it
> just looks like an initializer to me...)

I was afraid that 'instance' just was too long. An alternative is to use 'new' sort of like Ada. But you might be right.

> 2. How do I make two variables of type Foo(int)?

You don't - Foo is a template, not a type. A type could be declared inside the template:

    template Foo(T) { typedef T abc; }
    instance Foo(int) myfoo;
    // Declare multiple variables:
    myfoo.abc var1;
    myfoo.abc var2;

> According to the
> documentation, this appears to be explicitly disallowed -- "Multiple
> instantiations of a TemplateDeclaration with the same
TemplateParameterList all
> will refer to the same instantiation."  If I make a RedBlackTree(T), and
then
> find myself needing two separate trees that both hold char[]s, how can I
do
> that?  I *could* typedef two different names for char[]s and make separate instances that way, but that just obscures the issue.  Readers of the code
then
> have to go look up my typedef to find out that it is just a char[] with no additional functionality.

In that case, it sounds like one should write:

    template RedBlackTree(T)
    {
        class Foo
        { char[] s;
        }
    }

    instance RedBlackTree(whatever) mytree;

    // Now create multiple independent trees, each with their own data:
    mytree.Foo f = new mytree(Foo);
    mytree.Foo g = new mytree(Foo);

> 3. It might be useful to have some way to say that some template
parameters are
> "like" or "derived from" other template parameters:
>
> template Cage(Base, Derived like Base) {/*whatever*/}
>
> Then at instantiation:
>
> inst Cage(Bird, Cockateel);    // OK, assuming Cockateel derives from Bird
> inst Cage(Bird, Bird);         // OK
> inst Cage(Bird, Collie);       // Error - Collie does not derive from Bird
> inst Cage(Bird, Animal);       // Error - inheritance order is backwards
>
> I'm not sure how useful this is in practice.  I know Eiffel has a similar system, and Bertrand Meyer gets really excited about it, but I was never
certain
> that I saw the benefit of this over using Base*s and letting vtables
handle it.

That could possibly be handled by a contract:

    template Cage(Base, Derived)
    {
        class Foo
        {
            Base b;
            Derived d;
            invariant { assert(cast(Base)d != null); }
        }
    }

> 4. I would really like constrained genericity.  Similar to the above, but
when
> you say a parameter is "like" some base class, the base class doesn't need
to be
> another parameter to the template.
>
> template Calculator(T like NUMERIC) {/*whatever*/}
>
> In this case, NUMERIC is basically an interface.  The standard argument
against
> this is that if someone tries to instantiate the template with a class
that is
> not NUMERIC, something will fail when Calculator tries to use one of the
NUMERIC
> members.  But it is possible (even if unlikely) that a non-NUMERIC class
could
> accidentally implement enough of NUMERIC to let it work, but not work the
way
> Calculator expects.  Calculator is a bad example of this, since anyone
providing
> NUMERIC-style members probably is doing numerical work -- but for other templates and other interfaces, the issue is not as clear.  The other
benefit is
> self-documentation.  By placing it in the code, the developer makes it
clear
> what he/she is requiring for the template parameter.  It becomes part of
the
> contract.

That is a good suggestion. Note that there are already ways to constrain it to be, say, an array type:

    template Foo(T : T[])



August 21, 2002
"Suporte Internet" <suporte@spica.mps.com.br> wrote in message news:ak0dea$1ich$1@digitaldaemon.com...
> Why not use the keyword "typedef" ?
> This is not what is doing ? You are creating a new type based on a
> template ?

typedef is a good idea, the trouble comes from distinguishing a typedef from
a declaration just by
the syntax:

    typedef foo(int*) f;


August 21, 2002
Hmmm .... this "namespace" approach to templates leans toward ease of implementation, which is good.

Is there any way to do non-type template parameters?

template VectorNamespace(T, int S)
{
    class Vector
    {
        T[S] array;
    }
}

Also, I think that you should be able to do multiple specialization:

template Foo(T) { ... }
template Foo(T : int, float, double) { ... }

-Craig


August 21, 2002
Walter wrote:
> "Russ Lewis" <spamhole-2001-07-16@deming-os.org> wrote in message
> news:3D63793A.93407771@deming-os.org...
> 
>>max() and min() were presented to me as a classic problem that C++
>>templates were trying to solve.  The beauty was that there only needed
>>to be one declaration, and all types automatically got a max()
>>function.  It was a substitute for C's template solution.  I don't see
>>how D templates can do max and min, unless you explicitly instantiate
>>them:
>>    in Max(int) maxint; val3 = maxint.max(val1,val2);
>>That seems like an ugly solution to me, especially since (as I
>>understand it), we can't use the same instantiation name for multiple
>>different instantiations.  If we're going to have to have a "maxint"
>>template instantiation that's separate from a "maxfloat" and all the
>>others, we might as well just define functions and save ourselves 4
>>characters of typing when we call it.
> 
> 
> You are correct that D does not do C++'s implicit instantiation, in D,
> instantiation must be explicit. The reason is I have come to believe that
> much of the complexity and problems with C++ templates comes from implicit
> instantiation - this is complexity in both specification and use. In
> practice, I find that many programs use typedef's to try and reduce the
> complexity and approximate explicit instantiation.

That was only part of the problem.  I was also concerned about namespace cluttering (maxint, maxfloat, etc. instead of just a single "max").

August 21, 2002
Walter wrote:
> "Russ Lewis" <spamhole-2001-07-16@deming-os.org> wrote in message
> news:3D637991.FF91430E@deming-os.org...
> 
>>In the "Argument Deduction" section,  I don't understand the Bar(D, D :
>>D[]) example.  Does this mean that you have only one template parameter,
>>"D", and you have to specify it in 2 different ways?  If not, then what
>>does it mean?
> 
> 
> That defines, to use C++ terminology, a "partial specialization", and is
> equivalent to the C++:
> 
>     template<class D> int Bar<D, D[]>() { }
> 
> It means there are two arguments to the template, and to instantiate it you
> need to specify both. While this doesn't make a whole lot of sense by
> itself, it is to distinguish Bar(D,D[]) from another template Bar(D,E).

What is the difference between
    template Bar(D, D : D[]) {...}
and
    template Bar(D : D{}) {...}
?

August 21, 2002
Walter wrote:
> "Suporte Internet" <suporte@spica.mps.com.br> wrote in message
> news:ak0dea$1ich$1@digitaldaemon.com...
> 
>>Why not use the keyword "typedef" ?
>>This is not what is doing ? You are creating a new type based on a
>>template ?
> 
> 
> typedef is a good idea, the trouble comes from distinguishing a typedef from
> a declaration just by
> the syntax:
> 
>     typedef foo(int*) f;

You could go the old C route:
    typedef template foo(int*) f;

August 21, 2002
"Craig Black" <cblack@ara.com> wrote in message news:ak0h9n$1p37$1@digitaldaemon.com...
> Hmmm .... this "namespace" approach to templates leans toward ease of implementation, which is good.

It's a bit of an adjustment, but in the end I think it is superior.

> Is there any way to do non-type template parameters?
>
> template VectorNamespace(T, int S)
> {
>     class Vector
>     {
>         T[S] array;
>     }
> }

Not directly. It can be done indirectly as part of a type, or as a class member where the class is passed as a type parameter. I thought a lot about this, and decided that non-type parameters were rare, but added a lot of complexity to the parameters, so they weren't worth supporting directly.

> Also, I think that you should be able to do multiple specialization:
>
> template Foo(T) { ... }
> template Foo(T : int, float, double) { ... }

That can be faked using two templates, one instantiating the other.