【问题标题】:Ada structure member aliasesAda 结构成员别名
【发布时间】:2014-07-03 03:33:29
【问题描述】:

所以我在 Ada 中有一个(几何)矢量类型;这是成员xyz 的记录。

在某些情况下,我会想在其中存储颜色三元组,就像 GLSL 一样。红色值进入x,绿色值进入y,蓝色值进入z。因此,如果我可以使用rgb 作为x 的可互换别名,这将非常方便——并使我的代码更简单、更短、更易于理解并因此更易于维护。 yz(同样,就像 GLSL 一样)。

这个可以吗?

如果它是标记类型,那么我可以定义使用Implicit_Dereference 的方法来返回对xyz 成员的引用;这些将与真实的结构成员无缝互换。不幸的是,出于实现原因,我不能这样做 --- 这必须与 C 互操作,并且必须具有排除标记的特定结构布局。而且 AFAICT 方法语法仅适用于标记类型(这是一个奇怪的限制)。

建议?

【问题讨论】:

  • 我知道这适用于函数和包,但是如何使它适用于结构成员?
  • 几何向量是否与 Ada 端的颜色三元组共享相同的数据空间?还是 C 端的函数有时采用一种,有时采用另一种(大概用另一个参数来说明是什么意思)?还是别的什么?

标签: syntax structure ada


【解决方案1】:

您也许可以使用Unchecked_Union 方面,尽管有很多限制。它们中的大多数可能都不是问题,因为您想要 C 互操作。例如,

with Ada.Text_IO; use Ada.Text_IO;
procedure Aliasing_Components is
   type Vector (Colours : Boolean := False) is record
      case Colours is
         when False =>
            X, Y, Z : Integer;
         when True =>
            R, G, B : Integer;
      end case;
   end record
     with Unchecked_Union;
   V : Vector;
begin
   V := (Colours => False, X => 42, Y => 137, Z => 2014);
   Put_Line (Integer'Image (V.R));
end Aliasing_Components;

【讨论】:

  • 几乎 工作 --- 唯一的问题是结构文字要求我为 Colours 指定一个值,而我的程序中有无数个我现在不想改变。不过,这是我找到的最佳解决方案。
【解决方案2】:

为什么不使用子程序来做到这一点?

-- In Parent-Package
Type Geometric_Vector is
  X, Y, Z : Natural;
end record;

-- In child-package
Function R( Input : Geometric_Vector ) Return Natural is (input.R);
Function G( Input : Geometric_Vector ) Return Natural is (input.G);
Function B( Input : Geometric_Vector ) Return Natural is (input.B);
Procedure R( Object : in out Geometric_Vector; Value : Natural );
Procedure G( Object : in out Geometric_Vector; Value : Natural );
Procedure B( Object : in out Geometric_Vector; Value : Natural );

-- Child-package implementations:
Procedure R( Object : in out Geometric_Vector; Value : Natural ) is
begin
  Object.R:= Value;
end R;

Procedure G( Object : in out Geometric_Vector; Value : Natural ) is
begin
  Object.G:= Value;
end G;

Procedure B( Object : in out Geometric_Vector; Value : Natural ) is
begin
  Object.G:= Value;
end B;

【讨论】:

  • 这或多或少是我目前正在做的事情(尽管我使用引用类型来避免同时需要 setter 和 getter)。这种方法的问题在于它需要R(v) 而不是v.r,这非常笨拙。如果我可以在未标记的类型上使用方法语法调用,当然,这将是理想的。 (不是说我很苦,或者别的什么。)
  • 我错过了什么吗? Object.R := Value 是如何编译的,因为 Geometric_Vector 没有名为 R 的成员(而且您当然不能在 := 的左侧进行函数调用)?或者这只是一个错字?
  • 可以:=左边的函数调用——如果函数返回引用类型(即类型为@987654329的值@set 和所有其他使其工作的相当不明显的要求)。然后,该值将充当受限制的范围访问,但在您尝试使用它时会隐式取消引用。这就是例如container(7) := object 的工作方式。获取Object.R := Value 语法然后需要Object 成为标记类型,以便启用方法语法函数调用--- R 只是一个带有单个in out Object_Type 参数的函数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多