August 21, 2002
"Russell Lewis" <spamhole-2001-07-16@deming-os.org> wrote in message news:3D63CB8E.3030608@deming-os.org...
> 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;

I think I'd rather use the keyword 'instance' <g>.


August 21, 2002
"Russell Lewis" <spamhole-2001-07-16@deming-os.org> wrote in message news:3D63CB4E.30009@deming-os.org...
> Walter wrote:
> > 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{}) {...}
> ?

The latter is illegal, as D{} is not a type.


August 21, 2002
"Russell Lewis" <spamhole-2001-07-16@deming-os.org> wrote in message news:3D63C9DD.3060203@deming-os.org...
> Walter wrote:
> > 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").

The advantage of that is you'll get much more reasonable error messages, rather than things like:

    Error: foo<<<t>bar<<>>>const T>>>***<<T,Q><int <<<>>> bar<q,int*><10>

<g>


August 21, 2002
Walter wrote:
> "Russell Lewis" <spamhole-2001-07-16@deming-os.org> wrote in message
> news:3D63CB4E.30009@deming-os.org...
> 
>>Walter wrote:
>>
>>>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{}) {...}
>>?
> 
> 
> The latter is illegal, as D{} is not a type.

Oops, meant D[] on the latter one

August 21, 2002
>> 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;

Thank you.  I hadn't quite grokked that a template was a thing entirely to
itself.  The extra level of indirection (myfoo.abc rather than just abc(int))
had not really clicked.  Now that I see that, the RedBlack(char) question goes
away.

I really like being able to make an arbitrary amount of stuff inside a template, all based on the same instantiation parameters.  I'll have to think about it some more before I can give any useful feedback...

Mac


August 21, 2002
>> 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.

It is entirely possible that my current QWERTY -> DVORAK immersion retraining is just consuming too much of my mental flexibility quotient, but I suspect that some examples may be necessary to illustrate these solutions.  This could go on a page similar to your "Converting C to D" and "Converting C++ to D", where you could show the C++ methodology and then the corresponding D methodology.

Mac


August 21, 2002
Mac Reiter wrote:
> 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 agree. In addition, "in" is already used for "in" parameters and "in" contracts.

> 2. How do I make two variables of type Foo(int)?  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.
> 
> 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.
> 
> 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.
> 
> I have no particular attachment to the word "like" in either of the above
> points.  It just happened to be the first thing I thought of.  "implements"
> might not be a bad choice, although it is rather wordy ( T implements NUMERIC ).
> "isa" or "is_a" might work too ( T isa NUMERIC ).
> 
> Mac
> 
> 

August 21, 2002
Walter wrote:
> "Walter" <walter@digitalmars.com> wrote in message
> news:ajvgsb$6gt$1@digitaldaemon.com...
> 
>>www.digitalmars.com/template.html
>>Notice how short it is <g>. Ok, what did I miss?
> 
> 
> First thing I missed was the right url <sigh>
> 
> www.digitalmars.com/d/template.html
> 
> 
> 


Can you nest templates?  Would it be useful to be able to derive one template from another (to add memebers, not to override them)?

August 21, 2002
On Wed, 21 Aug 2002 00:56:13 -0700 "Walter" <walter@digitalmars.com> wrote:

> www.digitalmars.com/template.html
> 
> Notice how short it is <g>. Ok, what did I miss?

It's okay, but I think it could provide some more syntactic sugar.
It would be much better if we don't need to write a separate instantiation
for every template used in the program. Some in-place syntax would
be better. Something like this:

	template Container(T)
	{
		class Stack
		{
			private T[] pile;

			void push(T x)
			{
				pile ~= x;
			}

			T pop()
			{
				T x = pile[pile.length - 1];
				pile.length = pile.length - 1;
				return x;
			}
		}
	}

	Container(int).Stack s;

This is to avoid cluttering the namespace with continuous lists of instantiations (which is going to happen with any large program using templates extensively).
August 21, 2002
"Mac Reiter" <Mac_member@pathlink.com> wrote in message news:ak0m6l$2jt5$1@digitaldaemon.com...
> It is entirely possible that my current QWERTY -> DVORAK immersion
retraining is
> just consuming too much of my mental flexibility quotient, but I suspect
that
> some examples may be necessary to illustrate these solutions.  This could
go on
> a page similar to your "Converting C to D" and "Converting C++ to D",
where you
> could show the C++ methodology and then the corresponding D methodology.

You're quite right.