Ada 2012 - 将Fixed_Decimal_Type'Round()替换为自定义版本?



最近,我在为自定义记录类型提供自己的替换'Write ()过程时取得了令人高兴的成功,例如......

type Pixel_Format is
record
--  blah blah
end record;
procedure Pixel_Format_Write (
Stream : not null access Root_Stream_Type'Class;
Item : in Pixel_Format);
for Pixel_Format'Write use Pixel_Format_Write;

在写入网络流时,我使用它将某些记录成员从小端转换为大端。 工作得很好。

出于同样的想法,我想知道是否可以替换十进制不动点类型的'Round ()函数,所以我尝试了一个快速而肮脏的测试......

--  This is a "Decimal Fixed Point" type
type Money_Dec_Type is delta 0.001 digits 14;
--  ...
function Money_CustomRound(X : in Money_Dec_Type)
return Money_Dec_Type'Base;
for Money_Dec_Type'Round use Money_CustomRound; -- COMPILER COMPLAINS HERE
--  ...
function Money_CustomRound(X : in Money_Dec_Type)
return Money_Dec_Type'Base is
begin
return 0.001;
end Money_CustomRound;

唉,GNAT发现这种冒犯:

attribute "Round" cannot be set with definition clause

问题:

我在尝试不可能的事情吗? 或者有没有办法更改默认的'Round属性,就像可以更改'Write一样?

问题的背景:

我有一组大约 15 种不同的四舍五入货币值的方法,这些货币值从一个项目更改为下一个项目(有时在同一项目中! 示例包括:

  • 从零四舍五入(似乎是 Ada 的默认值(
  • 圆半朝零
  • 统计(需要全局内务管理的重入类型(
  • 四舍五入到偶数或赔率
  • 向 +INF/-INF 四舍五入

通过使用在通用包级别定义的某些舍入方法,能够使这种功能对程序员透明,这将是一个强大的工具。

我另一肩膀上的天使暗示我要求一些完全疯狂的东西。

我想知道这一点,因为文档(ALRM 和"Barnes 2012"(都为默认过程提供了函数规范。 如果一个人不能用另一个自己的设计来取代它,他们为什么要这样做?

不可以,不能重新定义Round属性。只能查询属性(请参阅 RM K.2(。只能使用方面规范(重新(定义方面(请参见 RM K.1;某些例外情况适用(。RM 提供了属性背后的函数规范,以向读者阐明签名。

最新更新