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

How can you store (an access to) Integer's operators in Ada?

在Ada中,上下文可以判断“+”不是String而是整数运算符,如表达式:"+"(5,2)。问题是,如何将该运算符存储在变量中?我想将那个整数运算符或其他某个运算符作为一个二元函数传递,它接受两个整数并返回一个整数。在下面的代码中,我创建了一个只调用运算符的显式函数,我可以将其用作解决方法。有什么方法可以避免使用这个包装器并直接传递(访问)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;

评论的声明显示了我所做的一些尝试,但无法编译。

恐怕你做不到。 Integer"+" 子程序在包 Standard [ARM A.1 (17)] and therefore intrinsic [AARM A.1 (2.a)]. It's not allowed to reference an intrinsic subprogram [ARM 3.10.2 (32.3)] 中定义。因此,编译程序

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;

和产量(如预期)

$ ./main_alt
          8
          2

我建议考虑使用泛型的不同方法。 一般来说,我认为你最终会得到一个更简单的调用界面,然后你 尝试传递对子程序参数的访问。 (即不需要每次调用都传递操作)。

使用泛型,您根本不需要使用 'Access,并且您可以传递内部函数,例如整数“+”,作为正式的泛型参数。

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)调用,或者如果您处于嵌套代码级别并且您传递给嵌套级别的所有内容都是对子程序值的访问。但我认为以其他方式使用泛型或至少将该选项视为首选通常是个好主意,除非你有充分的理由不这样做。