我是Delphi的新手。对于我公司所需的项目,我需要将一些代码从现有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运算符不适用于此操作数类型
AFAIK该代码应该工作,我不明白它有什么问题。所以有人可以向我解释:
为什么这样的代码不能在Delphi中编译?
在Delphi中创建一个模板类的正确(最简单)的方法是什么,该模板类提供一个Add()
函数,该函数尽可能接近上述C ++代码和用法?
修改于17.10.2016
感谢所有的答复。因此,如果我理解正确,就无法创建类似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)的必要性。因此,关于上面的代码,我的问题是:
最后,我在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;
我试图阅读幕后的代码,但是发现它非常复杂。因此,我的问题是:
提前感谢您的回复
问候
Delphi泛型不支持对泛型类型起作用的算术运算符。为了使编译器接受代码,它需要知道对通用类型的每个操作在实例化时将可用。
通用约束允许您告诉编译器类型具有哪些功能。但是,通用约束不允许您告诉编译器该类型支持arithmetjc运算符。
不幸的是,您试图做的事根本不可能。当然,您可以自己构造框架,使用诸如接口之类的工具来执行算法,但是这样做会降低性能。如果可以接受,那么可以。否则,最好是硬着头皮避免在这里使用泛型。
哦,对于C ++模板。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句