Operation can be dispatching in only one type
题
I have a record and wanted some accessor function for it.
package Some_Package is
type A is tagged record
First_Field : Integer;
Second_Field : Character;
end record;
type B is private;
function Some_A (Some_B : B) return A;
private
type B is tagged record
Some_A : A;
end record;
end Some_Package;
And here's what GNAT gives me:
some_package.ads:10:13: operation can be dispatching in only one type
This error is somewhat cryptic for Ada newbie and I'd appreciate some explanation what I did wrong and how to do it correctly.
解决方案
This is because of a specific rule in the ARM; there are two tagged types involved (B
privately), and in Ada a subprogram can dispatch on one of its parameters or on the function result (actually, it would be OK if all the parameters and the result were the same tagged type). I think this is a consequence of Ada’s single-inheritance design.
Do you actually need A
to be tagged? (I expect this is a cut-down version of the actual problem code).
If both A
and B
need to be tagged, the canonical solution for function Some_A
is to make one of its parameters/results class-wide (a class-wide parameter isn’t dispatching):
function Some_A (Some_B : B'Class) return A;
or
function Some_A (Some_B : B) return A'Class;
depending on which makes more sense from the application point of view; guessing the second, you can then say
The_A : A’Class := Some_A (Some_B => The_B);
By the way, it would be clearer to readers, and wouldn’t lose much encapsulation, if you said
type B is tagged private;