将TStack代码从Delphi转换为Lazarus

将TStack代码从Delphi转换为Lazarus,delphi,pascal,lazarus,Delphi,Pascal,Lazarus,在Delphi中,我有以下代码,所有代码都运行良好: var StackOptions:TStack<String>; s:string; bfisio:boolean; begin StackOptions:=TStack<String>.Create; //some pushs here for s in StackOptions do begin dosomething; end; end; var 堆栈选项:TStack;

在Delphi中,我有以下代码,所有代码都运行良好:

var
  StackOptions:TStack<String>;
  s:string;
  bfisio:boolean;
begin
  StackOptions:=TStack<String>.Create;
  //some pushs here 
  for s in StackOptions do begin
    dosomething;
  end;
end;
var
堆栈选项:TStack;
s:字符串;
bfisio:布尔型;
开始
StackOptions:=TStack.Create;
//这里有些推
对于StackOptions中的“开始”选项
剂量测定法;
结束;
结束;
在拉撒路,我可以做到:

uses
  ..., gstack;

type
  TStringStack = specialize TStack<String>;

var
  StackOptions: TStringStack;
  s:string;
begin
  //But this code doesn;t compile
  StackOptions := TStringStack.Create;
  //some pushs here 
  for s in StackOptions do begin // <-- Error 
    dosomething;
  end;
end;
使用
…,gstack;
类型
TStringStack=专门化TStack;
变量
堆栈选项:TStringStack;
s:字符串;
开始
//但是这个代码没有;不编译
StackOptions:=TStringStack.Create;
//这里有些推

对于StackOptions do begin中的s,FPC的堆栈由TVector支持。
TVector有一个枚举器

您可以像这样轻松地添加类帮助器:
快速而肮脏的代码

type
  TStringStack = specialize TStack<String>;

 type

   { TStackHelper }

   TVectorEnumerator = specialize TVector<string>.TVectorEnumerator;

   TStackHelper = class helper for TStringStack
     function GetEnumerator: TVectorEnumerator;
   end;

{ TStackHelper }

function TStackHelper.GetEnumerator: TVectorEnumerator;
begin
  Result:= FData.GetEnumerator;
end;
类型
TStringStack=专门化TStack;
类型
{TStackHelper}
TVector枚举器=专门化TVector.TVector枚举器;
TStackHelper=TStringStack的类帮助器
函数GetEnumerator:TVectorEnumerator;
结束;
{TStackHelper}
函数TStackHelper.GetEnumerator:TVectorEnumerator;
开始
结果:=FData.GetEnumerator;
结束;
我真的不明白为什么堆栈不应该有迭代器。
即使在汇编中,您也可以简单地执行
mov-reg[esp-04]

这种清教徒式的数据结构方法对任何人都没有帮助

由于TStack是通用的,所有这些都变得复杂起来。
我知道FPC允许通用类助手,但我不确定如何使解决方案适用于所有
TStack


另一种方法是简单地编辑
gstack.pas
以公开迭代器

您的数据结构不正确。如果你想搜索整个容器,你正在寻找一个列表。我正在尝试实现后进先出(LIFO),以撤消在我的应用程序中执行的一系列操作中所做的更改。我用应用程序的当前状态在堆栈中保存一个字符串,如果用户取消该操作,我将撤消更改。在delphi中,使用TStack可以很好地工作。然后我对拉撒路也做了同样的尝试。使用列表更好吗?如果您想访问整个容器,那么堆栈似乎是错误的。我希望您不能迭代gstack堆栈,因为它不支持迭代。我列出就行了。只是好奇,为什么你不想/能够在堆栈上迭代呢?例如,确定堆栈中是否存在某些内容,而不必弹出所有内容,然后再将所有内容推回(迭代器是检查程序,而不是修改器)。这似乎是一个合理的事情想要,有时甚至需要做。这大概就是为什么其他堆栈实现提供枚举器/迭代器支持?FreePascal的
TStack
类,包括泛型和非泛型变体,根本不支持任何类型的枚举,这正是错误消息所说的(“找不到枚举器”)。您可以获得
计数
,但无法访问单个项目,只能弹出/查看下一个要删除的项目。而Delphi
TStack
类支持枚举,我怀疑它是清教徒式的。如果您不需要支持迭代,我希望您可以生成优化的实现。我希望您会发现,在其他性能更为重要的语言中,这种情况确实会发生。除了STL之外,哪些语言出于性能原因而忽略了迭代?实际上,我不太确定STL堆栈中是否出于性能原因省略了迭代。