Ada:子类型转换或调用'Base

时间:2018-08-16 21:02:25

标签: types operator-overloading ada

我有以下一个简单问题:一种表示度数的delta型及其一个子类型,即angles,我将范围限制在0.0 .. <360.0之内。 现在,我想为子类型覆盖“ +”运算符以拥有我自己的模运算符:

package ...
type Degree is digits Degree_Digits;
end package

package ...
subtype Limited_Angle is Degree range Degree_Min .. Degree_Max;
function "+" (Left, Right : in Limited_Angle) return Limited_Angle;
end package

执行:

function "+" (Left, Right : in Limited_Angle) return Limited_Angle is
    res : Degree;
begin
    res := Units.Base.Degrees."+"(Left, Right);
    ...
    return Limited_Angle(res);
end "+";

但是我不喜欢这样,+运算符被称为。我的第一个想法是拥有

res := Degree(Left) + Degree(Right);

但这不起作用。我的编译器警告无限递归。 甚至更严格:

res := (Degree(Left)) + (Degree(Right));

警告无限递归。我不了解其背后的原理。 T(S)不应该将S转换为T吗? (T(S))也不起作用,所以这不是一个优化问题。

我是否错过了理解类型-子类型转换的概念(很可能是这样),并且有人有解决方案/解释吗?甚至是更好的解决方案?

谢谢!

2 个答案:

答案 0 :(得分:5)

您的问题与类型转换无关,而与了解类型和子类型之间的区别有关。

类型的所有子类型都具有完全相同的操作。一个类型的子类型之间的差异(包括类型本身,从技术上讲就是“该类型的第一个子类型”)只是允许值的集合。

这意味着您在DegreesLimited_Degrees之间进行的所有转换都做不了多少,而您对Units.Base.Degrees."+" (Left, Right)的调用实际上是递归调用。

我认为解决您的问题的方法是使Limited_Degrees成为派生类型,而不是子类型。

答案 1 :(得分:0)

目前没有可用的编译器,因此未经测试,但

res := Units.Base.Degrees."+"(Left, Right);

令人怀疑,因为您不需要为"+"left指定rightLimited_Angle的运算符"+"。所以我想知道上面的行是否正在调用当前的function "+" (Left, Right : in Degree) return Limited_Angle 运算符(因此是递归的)?

我会看看是否写:

"+"

是更好的选择,因为您可以在对Degree取模之前在Limited_Angle中进行Drop Table #MyTempTable Create Table #MyTempTable ( NAME NVARCHAR(100) ); Insert Into #MyTempTable VALUES ('3243') Insert Into #MyTempTable VALUES ('123') Insert Into #MyTempTable VALUES ('432423') Insert Into #MyTempTable VALUES ('423') Insert Into #MyTempTable VALUES ('432') select * from #MyTempTable Update #MyTempTable SET NAME = 'A' + REPLICATE('*', len(NAME) - 1) select * from #MyTempTable 的数学运算。这也将保存您的演员表。