gpt4 book ai didi

delphi - Delphi 中泛型类型的算术运算

转载 作者:行者123 更新时间:2023-12-03 14:57:02 24 4
gpt4 key购买 nike

我是德尔福新手。对于我公司需要的一个项目,我需要将一些代码从我们现有的 C++ 类转换为 Delphi。其中一些类是模板,例如:

template <class T>
struct APoint
{
T m_X;
T m_Y;

virtual void Add(T value);
};

template <class T>
void APoint<T>::Add(T value)
{
m_X += value;
m_Y += value;
}

我用它,例如使用此代码

APoint<float> pt;
pt.m_X = 2.0f;
pt.m_Y = 4.0f;
pt.Add(5.0f);

这效果很好。

现在我需要为 Delphi 编写等效的代码。我尝试根据上面的 C++ 代码编写一个 Delphi 通用类:

APoint<T> = record
m_X: T;
m_Y: T;

procedure Add(value: T);
end;

procedure APoint<T>.Add(value: T);
begin
m_X := m_X + value;
m_Y := m_Y + value;
end;

但是这段代码无法编译。我收到此错误:

E2015 Operator not applicable to this operand type

据我所知这段代码应该可以工作,但我不明白它有什么问题。那么有人可以向我解释一下吗:

  1. 为什么这样的代码不能在 Delphi 中编译?

  2. 在 Delphi 中创建提供 Add() 函数的模板类的正确(也是最简单)方法是什么,尽可能接近上面的 C++ 代码和用法?

已于 2016 年 10 月 17 日编辑

谢谢大家的回复。因此,如果我理解正确的话,则无法创建类似 C++ 的样式模板,因为 Delphi 强加了一些 C++ 中不存在的约束。

基于此,我寻找了一种解决方法来达到我想要的目标。我找到了以下解决方案:

IPoint<T> = interface
procedure Add(value: T);
end;

APoint<T> = class(TInterfacedObject, IPoint<T>)
m_X: T;
m_Y: T;

procedure Add(value: T); virtual; abstract;
end;

APointF = class(APoint<Single>)
destructor Destroy; override;
procedure Add(value: Single); reintroduce;
end;

destructor APointF.Destroy;
begin
inherited Destroy;
end;

procedure APointF.Add(value: Single);
begin
m_X := m_X + value;
m_Y := m_Y + value;
end;

我用它,例如使用此代码

procedure AddPoint;
var
pt: IPoint<Single>;
begin
pt := APointF.Create;

APointF(pt).m_X := 2.0;
APointF(pt).m_Y := 4.0;
APointF(pt).Add(5.0);
end;

这效果很好。不过我觉得风格有点厚重,例如使用APointF(pt)的必要性。因此,关于上面的代码,我的问题是:

  1. 这个解决方案是一个好的解决方案吗? (即最好为我想要支持的每种类型编写每个记录的版本,例如 APointF、APointI、APointD...)
  2. 有没有办法简化这段代码,例如直接调用 pt.m_X 而不进行 APointF(pt) 转换的解决方案? (注意我在这里省略了属性的实现,即使我认为它们比直接访问变量更优雅)
  3. 该解决方案的性能如何? (也就是说,这个解决方案比直接 m_X := m_X + 值加法慢得多吗?)

最后,我在 Delphi 代码中看到了另一个解决方案,可以通过这种方式实现 2 个泛型类型的相等比较:

function APoint<T>.IsEqual(const other: APoint<T>): Boolean;
var
comparer: IEqualityComparer<T>;
begin
Result := (comparer.Equals(m_X, other.m_X) and comparer.Equals(m_Y, other.m_Y));
end;

我尝试阅读幕后的代码,但发现它非常复杂。所以,我的问题是:

  1. 这样的解决方案比上面提出的解决方案更好吗?
  2. 是否有类似的即用型数学运算解决方案?
  3. 此类解决方案的性能可以接受吗?

提前感谢您的回复

问候

最佳答案

Delphi 泛型本质上不同于 C++ 模板,并且更类似于 C# 模板。

在 C++ 中,您可以对模板类型执行任何操作,并且在模板实例化时,编译器会检查您在模板中执行的操作是否适用于您正在使用的特定类型。如果不是,您会收到编译器错误。

在 Delphi(和许多其他语言)中,您声明一个泛型类型,可能会提供一些声明性约束,而这些约束(基类或接口(interface))决定您可以对泛型类型执行的操作。在实例化时,唯一的检查是声明的类型是否符合约束。

可以说,Delphi 语言可以添加对浮点或序数类型的约束,但这将提供非常有限的灵 active (更改可以在泛型实例中使用的浮点或整数类型)。我个人并不认为这是一个关键功能。

关于delphi - Delphi 中泛型类型的算术运算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40059579/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com