Re: Access to function returning class-wide type



Georg Bauhaus wrote:

Paweł 'Nivertius' Płazieński schrieb:

package B is
type Derived is new A.Abstracted with null record;
function Proc (N : Natural) return Derived;

Failing_Object : A.The_Access_Type := B.Proc'Access;
-- will not compile, error: 'expected type The_Access_Type /
found type
access function Proc defined at ...'
(Compiler is right because the profile of B.Proc is different
from that of The_Access_Type (whose functions return Abstracted'Class,
not Derived)

I made a test file:

package A is
type Abstracted is range 1 .. 100;
function Proc (N : Natural) return Abstracted;

type The_Access_Type is
access function (N : Natural) return Abstracted;
end A;

package body A is
function Proc (N : Natural) return Abstracted is
begin
return Abstracted (N);
end;
end A;

package B is
subtype Derived is A.Abstracted range 1 .. 10;
function Proc (N : Natural) return Derived;

Object : A.The_Access_Type := B.Proc'Access;
end B;

package body B is
function Proc (N : Natural) return Derived is
begin
return Derived (N);
end;
end B;

And this also fails to compile:
20. Object : A.The_Access_Type := B.Proc'Access;
|
>>> not subtype conformant with declaration at line 6
>>> return type does not match

So I assume that 'fully-conformant' means that types needs to be _exactly_
the same, not even implicitly conversible. That means that one wrapper or
another is required.

In general, public access types lead to unneccessary complication;
tagged types are by reference already, so you could simply use
dispatching and a factory instead. Do you have spefific needs
for pointers to functions returning by-reference objects?

Well, that was the example my problem boils down to. In real file the access
type is private within top-level package [in example it was A] and used
internally, not even in child packages.

function Proc_Wrapper(N : Natural) return Abstracted'Class is
begin
if N > 666 then -- and possibly Some_Other_Condition ...
declare
use B;
begin
return Derived'(Proc(N));
end;
else
--
-- other cases TBD
--
raise No_Suitable_Type;
end if;
end Proc_Wrapper;

First of all, the problem with that is, that I couldn't define conditions
and types for them dynamicaly.
Second (of all?), each new Derived type in child, or even remotely other
package needs to be hard-coded into examples package A.

I have a map between condition on an object of some type (in example it
was 'N') and access-to-function which creates the object derived from
Abstracted. I've also got funcion which gets the 'object of some type' and
for each key in the map checks if the condition is true. If so,
calls 'constructor' passing that 'object of some type' and returns its
result. If no condition is true, the function raises an exception.
(I probably should wrote that in original post).

--
Paweł Płazieński aka Nivertius
"In the end, there will be Ada, XML and gzip"
.



Relevant Pages

  • Access to function returning class-wide type
    ... Let me start with a tricky problem: ... type The_Access_Type is access function ... -- package A body ommited; ... function Proc return Derived; ...
    (comp.lang.ada)
  • Re: Access to function returning class-wide type
    ... -- package A body ommited; ... function Proc return Derived; ... different mechanisms for passing the return object between them. ... you need to write a wrapper anyway, you shouldn't have to rewrite the ...
    (comp.lang.ada)