From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=0.2 required=5.0 tests=BAYES_00,INVALID_MSGID, REPLYTO_WITHOUT_TO_CC autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,5d6741c4f70b756c,start X-Google-Attributes: gid103376,public From: Kevin Ingalls Subject: Dispatching in Generics Date: 1997/09/11 Message-ID: <34183CD3.7F4@boeing.com>#1/1 X-Deja-AN: 271657928 Sender: nntp@news.boeing.com (Boeing NNTP News Access) X-Nntp-Posting-Host: e593930.knt.boeing.com Organization: Boeing Reply-To: kevin.l.ingalls@boeing.com Newsgroups: comp.lang.ada Date: 1997-09-11T00:00:00+00:00 List-Id: Hello, I am trying to write a generic queue package in Ada95 will allow me to queue up objects that are of a type hierarchy. For example, I might have a parent tagged type A that has a derived type B and C. I want to be able to put an object of either type A, B, or C onto a queue. So, I use tagged types, hierarchical packages, generics, and classwide access types. Almost everything works. What doesn't work is dispatching with generics. Let's say that in this A,B,C hierarchy I have a primative operation "put". I want to be able to walk through my queue and "put" each element, and, of course, I want the correct "put" to be called (i.e., I want dispatching). How is this done? Here is a small example of the problem (the error message is from ObjectAda 7.1) ------------------Code Fragment----------------------- generic type T is tagged private; with procedure put (T1 : T); package G is procedure cant_dispatch(TC : T'class); end G; package body G is procedure cant_dispatch(TC : T'class) is begin put (TC); -- the error occurs here end cant_dispatch; end G; -----------------Error Message------------------------- cant_dispatch.ada: Error: line 11 col 14 LRM:3.9.2(9), If the expected type of a name or expression is a tagged type, then it shall not be dynamically tagged unless it is a controlling operand in a call on a dispatching operation, Continuing -----------------End of Error Message------------------ I understand why this doesn't work, but I don't know how to get around it. The only work-around that I have found so far is to add a classwide operation to the A,B,C hierarchy. The classwide operation simply does a dispatching call to the primative operation. I then change the generic formal parameter to take the classwide operation, instead of the primitive operation. However, this violates the spirit of generics in that it requires the generic actual type to know that a classwide operation is needed for the generic to work correctly. That is, my goal was to write a generic queue that could take objects of *any* hierarchy, not only those that have a classwide operation bolted on. My second question is why is this so difficult to do? Maybe when the answer is pointed out to me, I'll take that back :-), but this seems like a fairly straight-forward use to the language. I'm hardly a proponant of C++, but I wrote the C++ version of this problem in about 1/2 an hour. What important software engineering concept is being violated in what I am trying to do? Thanks for any insight you might have. -- Kevin Ingalls kevin.l.ingalls@boeing.com (253)773-9404