Take the 2-minute tour ×

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;                                           


   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.

share|improve this question
add comment

1 Answer

up vote 7 down vote accepted

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;


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;
share|improve this answer
Great answer. There's only one thing I'd like to see clarified - what exactly 'to dispatch' means in this context? I tried some googling but it is used differently for different things in Ada context. –  Mikołaj Siedlarek Jul 25 '12 at 11:37
@Mikolaj: Check out the chapter on Object Orientation in the Ada Wikibook, dispatching in particular. –  Marc C Jul 25 '12 at 13:47
@MarcC, I copied your link into the answer. Thanks. –  Simon Wright Jul 25 '12 at 14:38
Now, with links, everything's crystal clear. Thanks! –  Mikołaj Siedlarek Jul 25 '12 at 15:09
See also this about the dispatch table Dispatch table. I think (corrections welcome!) that your some_package code would have required 2 tables (Not one - Single inheritance) and therefore the code could not dynamically determine which table to use to dispatch on. –  NWS Jul 26 '12 at 9:19
add comment

Your Answer


