【问题标题】:Ada: Subtype Conversion or calling 'BaseAda:子类型转换或调用'Base
【发布时间】:2018-08-16 21:02:24
【问题描述】:

我有以下-简单-问题:用于表示度数的增量类型及其子类型角度,我将范围限制为 0.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)) 也不起作用。

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

谢谢!

【问题讨论】:

    标签: types operator-overloading ada


    【解决方案1】:

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

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

    这意味着您在DegreesLimited_Degrees 之间的所有转换都没有多大作用,而您对Units.Base.Degrees."+" (Left, Right) 的调用实际上是一个递归调用。

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

    【讨论】:

      【解决方案2】:

      目前没有可用的编译器,所以没有测试,但是

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

      很可疑,因为您不需要为leftright 指定运算符"+",它们是Limited_Angle。所以我想知道上面的行是否正在调用当前的"+" 运算符(因此是递归的)?

      我会看看是否写:

      function "+" (Left, Right : in Degree) return Limited_Angle 
      

      这是一个更好的选择,因为您可以在 Degree 中进行 "+" 数学运算,然后再将 (ing) 到 Limited_Angle。这也将节省您的待命演员。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-03-22
        • 2011-07-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多