为什么前缀呼叫对访问类型不起作用?

时间:2019-09-17 09:22:10

标签: ada

我在程序包中有一些方法可以对带有标记记录的访问常量进行操作;为了调用这些函数,我必须指定程序包名称。我宁愿只输入变量名[dot]函数名,但这会导致错误:no selector "foo" for type "Color"。为什么会这样?

这里是最小的复制者:

procedure Main is

  type Color is tagged
    record
      Hue : Integer;
      Saturation : Integer;
      Value : Integer;
    end record;

  type AccessColor is access constant Color;

  procedure foo (C : in AccessColor) is
  begin
    null;
  end foo;

  AccessS : AccessColor;

begin
  foo (AccessS);
  --AccessS.foo; -- does not work. Why?
end Main;

请注意,在我的实际代码中,完全指定该函数很不方便,因为与上面的示例不同,foo是在单独的程序包中的某个位置定义的:

Some.Package.Name.Depp.foo(AccessS);

即使AccessS已经指定了在哪里可以找到该函数,所以我应该能够做到:

AccessS.foo;

2 个答案:

答案 0 :(得分:5)

这不起作用,因为根据您的定义,foo不是标记类型为Color原始操作。前缀表示法只能用于标记类型的原始操作。

解决方案是使foo成为Color的原始操作,如下所示:

procedure foo (C : access constant Color) is
begin
   null;
end foo;

如果您使用命名访问类型,则foo将是该类型的原始操作,并且由于该类型不是标记类型,因此前缀表示法不起作用。

答案 1 :(得分:5)

问题在于foo实际上不是Color的原始操作(在此复制器中)。

ARM 3.3.2(6)说特定类型的原始子程序是

  

对于在package_specification中立即声明的特定类型 在同一package_specification中立即明确声明的所有子程序(除枚举常量外)类型

这个(重新格式化,调整大小写的歉意)编译得很好。

procedure Main is

   package Pak is

      type Color is tagged
         record
            Hue : Integer;
            Saturation : Integer;
            Value : Integer;
         end record;

      procedure Foo (C : in Color) is null;

      type AccessColor is access constant Color;

   end Pak;

   Col : aliased Pak.Color;

   AccessS : Pak.AccessColor := Col'Access;

begin
   AccessS.Foo;
end Main;

我宣布Foo服用in Color;您也可以根据需要将其声明为采用access constant Color,因为(ARM 4.1.3(9.2)

  

子程序的第一个形式参数应为T类型,或覆盖T的全类类型,或指定这些类型之一的访问参数。