operator-overloading - 为什么在 Ada 中不允许匿名访问对象之间的隐式转换?
问题描述
我正在阅读 Barnes 的《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;
我添加了一条评论,其中包含 gnat 给我的错误。为什么我不允许从一个匿名转换access Cell
为另一个?
我可以通过反转条件来解决问题:
return not (SS /= TT);
正如约翰·巴恩斯(John Barnes)早些时候所说,如果您定义一个返回布尔值的“=”运算符,这让我感到困惑,那么会自动为您生成反的“/=”,这意味着相反。
类似地,循环条件可以反转,在这种情况下,它无法使用相同的消息进行编译。
最后,附注:程序的预期行为,它在更改后给出的return not (SS /= TT)
是无限递归并由于堆栈溢出而引发 storage_error。在这个其他 SO question中可以更好地看到其原因,并且不是这个问题的主题。
为什么我写“=”时编译器不允许转换?为什么我写“/=”时会有所不同,我认为这总是相反的?
为自己编译示例所需的其他文件:
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;
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;
堆栈.gpr:
project stacks is
for Source_Dirs use ("src");
for Object_Dir use "obj";
for Main use ("main.adb");
end stacks;
生成文件:
all:
gprbuild -d -p -g
clean:
rm -rf obj *.o *.ali
或者用 gcc 编译:
gcc -c src/*.adb
gnatbind main
gnatlink main
它给出了相同的结果。
解决方案
推荐阅读
- loops - 如何在 Autohotkey 中使用“Loop,Parse”切换一串热键?
- payment-gateway - PrestaShop 插件问题
- ionic-framework - 图片未在 gmail 上使用社交分享插件分享
- python - 如何合并和更新熊猫数据框
- python - 如何为 Python 3.7.2 安装 Pycrypto?
- string - str_to_hive 函数将字符串的每个字符拆分为键
- sql - 在 where 子句中使用 if not exists
- javascript - Href 链接目标 在移动视图的同一选项卡中打开
- swift - 如何在我的 swift 框架中使用核心数据
- sql-server - sql server中的case和if子句