From: Niklas Holsti <niklas.holsti@tidorum.invalid>
Subject: Re: Renaming of procedures in a generic instantiation
Date: Sun, 26 Sep 2010 09:54:15 +0300
Date: 2010-09-26T09:54:15+03:00 [thread overview]
Message-ID: <8g890nFmqiU1@mid.individual.net> (raw)
In-Reply-To: <f0affc67-0080-410f-9595-b91f893ec6f5@a19g2000yql.googlegroups.com>
Gene wrote:
> I'm confused about an aspect of renaming. It boils out to this little
> example:
>
> with Ada.Containers.Ordered_Sets;
>
> package Foo is
>
> type Queue is private;
>
> procedure Add(Q : in out Queue; Item : in Integer);
>
> function Is_Empty(Q : Queue) return Boolean;
>
> private
>
> package Queues is
> new Ada.Containers.Ordered_Sets(Integer, "<", "=");
> type Queue is new Queues.Set with null record;
>
> end Foo;
>
> package body Foo is
>
> procedure Add(Q : in out Queue; Item : in Integer)
> renames Insert;
>
> function Is_Empty(Q : Queue) return Boolean
> renames Queues.Is_Empty;
>
> end Foo;
>
> The renaming in Add "finds" the correct procedure Insert, but the
> renaming of Is_Empty fails:
>
> gnatmake foo.adb
> gcc -c foo.adb
> foo.adb:6:04: no visible subprogram matches the specification for
> "Is_Empty"
> foo.adb:6:13: expected private type "Ada.Containers.Ordered_Sets.Set"
> from insta
> nce at foo.ads:14
> foo.adb:6:13: found type "Queue" defined at foo.ads:16
> gnatmake: "foo.adb" compilation error
>
> I guess I can see this error because a parameter type conversion is
> implied in the renaming. But then why does the renaming of Insert
> work correctly?
The type derivation
type Queue is new Queues.Set with null record;
makes type Queue inherit the primitive operations of Queues.Set by
implicitly declaring (within package Foo) corresponding operations on
type Queue. These include the operation Insert with the profile:
procedure Insert (
Container : in out Queue;
New_Item : in Integer);
This profile matches that of Foo.Add, and so Foo.Add can be a renaming
of this Insert. By the way, this implicitly declared Insert (on Queue)
has the qualified name Foo.Insert, not Queues.Insert.
The type derivation also "tries" to declare implicitly the Is_Empty
operation from Queues, with the profile:
function Is_Empty (Container : Queue) return Boolean;
but this operation clashes with (has the same name and same profile as)
the operation Is_Empty that was already and explicitly declared in Foo
(before the "private"), so they cannot both be visible. If I understand
correctly, the rule RM 8.3(10/1) says that the first, explicit
declaration overrides the second, implicit declaration (because the
first declaration is not "overridable").
So what saves you in the Insert/Add case is that the operation names are
different, which means there is no clash. It is a bit irritating that
the "simpler" case, with the same names, does not work in the same way.
I have at times had the same problem, where I have been disappointed
that implementing a private type as a derived type does not implicitly
complete the declarations of matching operations, such as Is_Empty in
this example. I would have liked to be able to write something like:
type Queue is new Queues.Set with null record
overriding Is_Empty (Q : Queue) return Boolean; -- Not Ada!
No doubt you have already found a solution for Is_Empty, but anyway here
is what I would do:
function Is_Empty (Q : Queue) return Boolean
is
begin
return Queues.Is_Empty (Queues.Set (Q));
end Is_Empty;
--
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
. @ .
next prev parent reply other threads:[~2010-09-26 6:54 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-09-26 0:43 Renaming of procedures in a generic instantiation Gene
2010-09-26 6:54 ` Niklas Holsti [this message]
2010-09-26 7:40 ` Jeffrey Carter
2010-09-26 8:41 ` Niklas Holsti
2010-09-26 17:07 ` Jeffrey Carter
2010-09-26 14:52 ` Gene
2010-09-26 15:04 ` Dmitry A. Kazakov
2010-09-26 8:45 ` Stephen Leake
2010-09-26 9:11 ` Niklas Holsti
2010-09-27 1:18 ` Gene
2010-09-28 11:36 ` Stephen Leake
2010-09-29 1:25 ` Gene
2010-09-27 19:23 ` Adam Beneschan
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox