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=-1.9 required=5.0 tests=BAYES_00 autolearn=unavailable autolearn_force=no version=3.4.4 Path: eternal-september.org!reader01.eternal-september.org!reader02.eternal-september.org!news.eternal-september.org!mx02.eternal-september.org!feeder.eternal-september.org!newsfeed.fsmpi.rwth-aachen.de!newsfeed.straub-nv.de!reality.xs3.de!news.jacob-sparre.dk!loke.jacob-sparre.dk!pnx.dk!.POSTED!not-for-mail From: "Randy Brukardt" Newsgroups: comp.lang.ada Subject: Re: Design of cross referring types/classes and proper usage of containers Date: Sat, 8 Aug 2015 22:11:03 -0500 Organization: Jacob Sparre Andersen Research & Innovation Message-ID: References: <12wxvkghwgpw3.k4qf1rqnppjb$.dlg@40tude.net> <8b424e66-337a-4943-91d1-e421312b5c95@googlegroups.com> <186o8cox1jqwa.yahqsx8p0k84$.dlg@40tude.net> <3341271b-4926-40cb-a9aa-660522d56f24@googlegroups.com> <34d1bef3-5d7b-4420-8256-7227d5792a13@googlegroups.com> NNTP-Posting-Host: rrsoftware.com X-Trace: loke.gir.dk 1439089865 10168 24.196.82.226 (9 Aug 2015 03:11:05 GMT) X-Complaints-To: news@jacob-sparre.dk NNTP-Posting-Date: Sun, 9 Aug 2015 03:11:05 +0000 (UTC) X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 6.00.2900.5931 X-RFC2646: Format=Flowed; Original X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.6157 Xref: news.eternal-september.org comp.lang.ada:27394 Date: 2015-08-08T22:11:03-05:00 List-Id: "Serge Robyns" wrote in message news:34d1bef3-5d7b-4420-8256-7227d5792a13@googlegroups.com... ... > return T_Subscription_Access (Subscriptions.Reference (Cursor)); ... >And the compiler moans on the return in the else part => >ambiguous operand in conversion >possible interpretation at a-coorma.ads:104, instance at line 25 >possible interpretation at a-coorma.ads:113, instance at line 25 The operand of a type conversion has to be resolvable without using any context. But I'd expect that to be OK in this case, as the Cursor should disambiuate it. Probably the real problem is that Reference doesn't return an access but rather a "Reference_Type" which has the "Implicit_Dereference" aspect. The compiler can't know whether or not to use that aspect, as there is no context, so it tries both and gives this error. (Not the clearest error message ever, but Ada resolution rarely leads to great error messages, since it is just a yes or no answer, and the number of reasons for "no" can seem infinite.) Write out the reference to the discriminant of the Reference_Type and this problem ought to go away. (I can't try it since you didn't post a complete program.) return T_Subscription_Access (Subscriptions.Reference (Cursor).Element); However, I think you'll find that you get a different error here. The containers are designed such that you can only get a short-lived access into them, and here you are assigning this into a long-lived access type. Thus you ought to get an accessibility error. I'd probably try to avoid returning an access at all; for reading purposes, you can just return a copy of the subscription; and for writing purposes I'd suggest having the Subscription package do that (that is, it would contain some procedures for altering particular Subscriptions). If that's too much disruption for your design, you can try going over to the dark side and use an anonymous access return type. That will push the accessibility check to run-time; so long as the caller doesn't try to store the resulting access, they ought to be able to use it just as you can use Reference. OTOH, if they try to put into a long-lived type, Program_Error will be raised by the return statement. In this case, you do not want there to be a type T_Subscription_Access, as that would encourage clients to use it (causing the exception). This would look like: function Get_Subscription (Subscription_Name : in T_Subscription_Name) return access T_Subscription is Cursor : Subscription_Map.Cursor; begin Cursor := Subscriptions.Find (Subscription_Name); if Cursor = Subscription_Map.No_Element then return null; else return Subscriptions.Reference (Cursor).Element; end if; end Get_Subscription; You could also return the Reference_Type itself (slightly safer, as clients would get a compile-time failure). But that would messy (probably you'd want to make it a private type and then derive it from the Reference_Type of the instance). I can show you what I mean on Monday if you can't figure it out yourself (I'll have to code up something to see if it actually works). In any case, the point is that if you are going to eliminate the access types, you really need to eliminate all of them! Leaving some is problematical. Randy.