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.3 required=5.0 tests=BAYES_00, REPLYTO_WITHOUT_TO_CC autolearn=no autolearn_force=no version=3.4.4 X-Google-Thread: 103376,1e36228aae0595da X-Google-Attributes: gid103376,domainid0,public,usenet X-Google-Language: ENGLISH,ASCII Path: g2news1.google.com!news3.google.com!feeder1-2.proxad.net!proxad.net!feeder2-2.proxad.net!newsfeed.arcor.de!newsspool4.arcor-online.net!news.arcor.de.POSTED!not-for-mail From: "Dmitry A. Kazakov" Subject: Re: Access to function returning class-wide type Newsgroups: comp.lang.ada User-Agent: 40tude_Dialog/2.0.15.1 MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-2" Content-Transfer-Encoding: 8bit Reply-To: mailbox@dmitry-kazakov.de Organization: cbb software GmbH References: Date: Thu, 21 Aug 2008 15:34:39 +0200 Message-ID: NNTP-Posting-Date: 21 Aug 2008 15:34:42 CEST NNTP-Posting-Host: 403c5ce0.newsspool1.arcor-online.net X-Trace: DXC=NMSf^>Y[CHZYQ5E:l On Thu, 21 Aug 2008 13:56:35 +0200, Pawe� 'Nivertius' P�azie�ski wrote: > Dmitry A. Kazakov wrote: > >>> What I need is a access type to 'constructor' of an derivate of abstract >>> object. >>> As I presented, there is a workaround, but that's not the 'right' way to >>> do it. I really want to do it without some tricky wrapping. >>> How do I define The_Access_Type to do what I want? >> See Ada.Tags.Generic_Dispatching_Constructor. It gives you a function >> constructing an object from the type tag, the parameters (Natural in your >> case) using the function you want (Proc). It goes as follows: >> >> with Ada.Tags.Generic_Dispatching_Constructor; >> package A is >> type Abstracted is abstract tagged null record; >> function Proc (N : not null access Natural) >> return Abstracted is abstract; >> function Constructor is >> new Ada.Tags.Generic_Dispatching_Constructor >> (Abstracted, Natural, Proc); >> end A; > > I belive that would work too, but at the cost of defining function Proc (N : > not null access Natural) return ... for each descendant type. Yes, it is the body of the "constructor". > That would be > another wrapper, so it's the same resolution to the problem as Proc_Wrapper > in my original code, assuming that I need Proc (N : Natural) as well. Not really, because it would replace old Proc completely. The idea is: with Ada.Tags; use Ada.Tags; package A is type Abstracted is abstract tagged null record; -- To be used function Factory (T : Tag; N : Natural) return Abstracted'Class; -- Implementation detail, to be provided by each derived type function Proc (N : not null access Natural) return Abstracted is abstract; end A; with Ada.Tags.Generic_Dispatching_Constructor; package body A is function Make_It is new Generic_Dispatching_Constructor (Abstracted, Natural, Proc); function Factory (T : Tag; N : Natural) return Abstracted'Class is Parameters : aliased Natural := N; begin return Make_It (T, Parameters'Access); end Factory; end A; Now, when you derive from Abstracted you override Proc and that's all you need to keep Factory working: type Concrete is new Abstracted with private; overriding Proc (N : not null access Natural return Concrete; In short, the solution replaces pointer->constructor with tag->constructor. Both enforced to be overridden. P.S. I don't know reasons why it was decided to use an access type in Ada.Tags.Generic_Dispatching_Constructor profile. One could always pass a pointer there if a side effect on the parameters were desired. But that is another issue, and in any case Proc is thought as an implementation detail, so its exact profile should not really matter. -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de