comp.lang.ada
 help / color / mirror / Atom feed
From: "Randy Brukardt" <randy@rrsoftware.com>
Subject: Re: Design of cross referring types/classes and proper usage of containers
Date: Sat, 8 Aug 2015 22:11:03 -0500
Date: 2015-08-08T22:11:03-05:00	[thread overview]
Message-ID: <mq6gc9$9to$1@loke.gir.dk> (raw)
In-Reply-To: 34d1bef3-5d7b-4420-8256-7227d5792a13@googlegroups.com

"Serge Robyns" <serge.robyns@gmail.com> 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.



  reply	other threads:[~2015-08-09  3:11 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-08-03 16:08 Design of cross referring types/classes and proper usage of containers Serge Robyns
2015-08-03 16:14 ` Serge Robyns
2015-08-03 20:17   ` Georg Bauhaus
2015-08-03 16:22 ` Dmitry A. Kazakov
2015-08-04 11:43   ` Serge Robyns
2015-08-04 12:13     ` Dmitry A. Kazakov
2015-08-04 19:00       ` Serge Robyns
2015-08-04 19:20         ` Jeffrey R. Carter
2015-08-04 20:27         ` Randy Brukardt
2015-08-04 21:21         ` Simon Wright
2015-08-08 11:25           ` Serge Robyns
2015-08-09  3:11             ` Randy Brukardt [this message]
2015-08-09 13:33               ` Serge Robyns
2015-08-05  7:37         ` Dmitry A. Kazakov
2015-08-05 17:51           ` Serge Robyns
2015-08-05 19:21             ` Dmitry A. Kazakov
2015-08-06  7:00               ` Georg Bauhaus
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox