Tam*_*inn 6 operator-overloading ada
我正在阅读 Barnes 的书“Programming in Ada 2012”。这是实现第 12.5 节中的堆栈的代码示例。
src/stacks.adb:(主要相关文件)
package body Stacks is
procedure Push(S: in out Stack; X: in Integer) is
begin
S := new Cell'(S,X);
end Push;
procedure Pop(S: in out Stack; X: in out Integer) is
begin
X := S.Value;
S := Stack(S.Next);
end Pop;
function "="(S, T: Stack) return Boolean is
SS: access Cell := S;
TT: access Cell := T;
begin
while SS /= null and TT /= null loop
if SS.Value /= TT.Value then
return false;
end if;
SS := SS.Next;
TT := TT.Next;
end loop;
return SS = TT; -- error: implicit conversion of stand-alone anonymous access object not allowed
end "=";
end Stacks;
Run Code Online (Sandbox Code Playgroud)
我添加了一条评论,其中包含 gnat 给我的错误。为什么我不允许从一个匿名转换access Cell为另一个匿名?
我可以通过反转条件来解决问题:
return not (SS /= TT);
Run Code Online (Sandbox Code Playgroud)
这让我很困惑,因为约翰·巴恩斯之前说过,如果你定义一个返回布尔值的“=”运算符,那么会自动为你生成相反的“/=”,意思相反。
同样,循环条件可以反转,在这种情况下,它无法使用相同的消息进行编译。
最后,旁注:程序的预期行为,在更改为之后给出的return not (SS /= TT)是无限递归并由于堆栈溢出而引发 storage_error 。其原因可以在另一个 SO 问题中更好地看出,并且不是这个问题的主题。
为什么我写“=”时编译器不允许转换?为什么当我写“/=”时会有所不同,我认为它总是相反的?
自己编译示例所需的其他文件:
src/stacks.ads:
package Stacks is
type Stack is limited private;
procedure Push(S: in out Stack; X: in Integer);
procedure Pop(S: in out Stack; X: in out Integer);
function "="(S, T: Stack) return Boolean;
private
type Cell is
record
Next: access Cell;
Value: Integer;
end record;
type Stack is access all Cell;
end;
Run Code Online (Sandbox Code Playgroud)
src/main.adb:
with Ada.Text_IO; use Ada.Text_IO;
with Stacks; use Stacks;
procedure Main is
A : Stack;
B : Stack;
begin
Push(A, 1);
Push(B, 1);
Push(A, 2);
Push(B, 2);
Push(A, 1);
Push(B, 1);
Push(A, 8);
Push(B, 8);
declare
Same : Boolean := A = B;
Text : String := (if Same then "They are the same" else "They are not the same");
begin
Put_Line(Text);
end;
end Main;
Run Code Online (Sandbox Code Playgroud)
堆栈.gpr:
project stacks is
for Source_Dirs use ("src");
for Object_Dir use "obj";
for Main use ("main.adb");
end stacks;
Run Code Online (Sandbox Code Playgroud)
生成文件:
all:
gprbuild -d -p -g
clean:
rm -rf obj *.o *.ali
Run Code Online (Sandbox Code Playgroud)
或者用 gcc 编译:
gcc -c src/*.adb
gnatbind main
gnatlink main
Run Code Online (Sandbox Code Playgroud)
它给出相同的结果。