您如何在Ada中存储(访问)Integer的运算符?

时间:2019-06-13 19:41:28

标签: ada

在Ada中,上下文可以确定“ +”不是字符串而是整数运算符,如表达式"+"(5,2)中所示。问题是,如何将该运算符存储在变量中?我想将该整数运算符或其他一些运算符作为接受两个Integer并返回Integer的二进制函数传递。在下面的代码中,我做了一个明确的函数,它仅调用运算符,可以将其用作解决方法。有什么方法可以避免使用此包装器,而直接传递(访问)Integer的“ +”运算符?

with Ada.Text_IO; use Ada.Text_IO;

procedure operator is

  type binary_int_operator is access function(lhs : Integer; rhs : Integer) return Integer;

  --plus : binary_int_operator := Integer."+"'Access;
  --plus : binary_int_operator := Integer'Access("+");
  --plus : binary_int_operator := Integer'"+";
  --plus : binary_int_operator := "+";

  function plus(lhs : Integer; rhs : Integer) return Integer is
  begin
    return lhs + rhs;
  end plus;

begin
  Put_Line(Integer'Image("+"(5, 12)));
end operator;

带注释的声明显示了我所做的一些尝试,这些尝试无法编译。

2 个答案:

答案 0 :(得分:8)

恐怕你不能那样做。 "+"的{​​{1}}子程序在包Integer [ARM A.1 (17)]中定义,因此是固有的[AARM A.1 (2.a)]。不允许引用内部子程序[ARM 3.10.2 (32.3)]。因此,编译程序

Standard

收益

procedure Main is

   type Binary_Int_Operator is
     access function (lhs : Integer; rhs : Integer) return Integer;

   Plus : Binary_Int_Operator := Standard."+"'Access;

begin
   null;
end Main;

唯一的解决方法是使用间接寻址。该程序编译

6:34 prefix of "Access" attribute cannot be intrinsic

和产量(符合预期)

with Ada.Text_IO;         use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;

procedure Main_Alt is

   type Operation is
     access function (Lhs, Rhs : Integer) return Integer;


   --  Sticking to "+" and "-" instead of names like Add or Subtract
   --  to demonstrate that you can reference operator subprograms
   --  (using the Access attribute) as long as they're not intrinsic.

   function "+" (Lhs, Rhs : Integer) return Integer is
     (Standard."+" (Lhs, Rhs));

   function "-" (Lhs, Rhs : Integer) return Integer is
     (Standard."-" (Lhs, Rhs));


   procedure Calc_And_Show (Lhs, Rhs : Integer; Op : Operation) is
   begin
      Put (Op (lhs, rhs));
      New_Line;
   end Calc_And_Show;

begin
   Calc_And_Show (5, 3, "+"'Access); 
   Calc_And_Show (5, 3, "-"'Access);
end Main_Alt;

答案 1 :(得分:2)

我建议考虑使用泛型的另一种方法。 一般来说,我认为您的通话最终会得到一个更简单的界面, 尝试传递对子程序参数的访问权限。 (即无需为每个调用传递操作)。

使用泛型,您根本不需要使用“访问”,并且可以将诸如整数“ +”的内在函数作为正式的泛型参数传递。

with Ada.Text_IO;         use Ada.Text_IO;
with Ada.Integer_Text_IO; use Ada.Integer_Text_IO;

procedure Main is

   generic
      with function Op (L, R : Integer) return Integer;
   procedure Calc_And_Show (Lhs, Rhs : Integer);

   procedure Calc_And_Show (Lhs, Rhs : Integer) is
   begin
      Put (Op (lhs, rhs));
      New_Line;
   end Calc_And_Show;

   procedure Calc_And_Show_Plus is new Calc_And_Show (Op => "+");
   procedure Calc_And_Show_Minus is new Calc_And_Show (Op => "-");

begin
   Calc_And_Show_Plus  (5, 3); 
   Calc_And_Show_Minus (5, 3);   
end Main;

可能有一些原因,您想改用访问参数,例如,希望Calc_And_Show可从其他语言(如C)中调用,或者您处于嵌套的代码级别,并且已将所有内容传递给您的嵌套级别是对子程序值的访问。但是我认为,除非您有充分的理由不使用泛型,否则至少将该选项作为首选是一个好主意。