August 21, 2002 Re: template proposal | ||||
---|---|---|---|---|
| ||||
Posted in reply to anderson | "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 Re: template proposal | ||||
---|---|---|---|---|
| ||||
Posted in reply to Russ Lewis | "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 Re: template proposal | ||||
---|---|---|---|---|
| ||||
Posted in reply to anderson | "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 Re: template proposal | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mac Reiter | "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 Re: template proposal | ||||
---|---|---|---|---|
| ||||
Posted in reply to Suporte Internet | "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 Re: template proposal | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | 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 Re: template proposal | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | 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 Re: template proposal | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | 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 Re: template proposal | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | 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 Re: template proposal | ||||
---|---|---|---|---|
| ||||
Posted in reply to Craig Black | "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. |
Copyright © 1999-2021 by the D Language Foundation