Преобразование типов в ада

У меня есть пакет, в котором я конвертирую строку в целое число следующим образом:

param: integer;
begin
param:= Integer'Value(param_string);

Мой вопрос очень простой, я хотел бы сделать то же самое, но с универсальным пакетом. Универсальный тип — TypeElement. Однако я не могу этого сделать:

param: TypeElement;
begin
param:= TypeElement'Value(param_string);

Ошибка "префикс атрибута "значение" должен быть скалярным типом"

Есть ли хитрость?


ada
person Flatbeat    schedule 09.04.2011    source источник


Ответы (1)


Универсальный формальный тип, предоставляемый для TypeElement, должен представлять скалярный тип.

Если вы объявляете его частным, например:

generic
   type TypeElement is private;

тогда это не сработает, потому что нет гарантии, что TypeElement будет скалярным типом, который, как вы обнаружили, требуется для использования атрибута «Value». Вам необходимо использовать одно из общих формальных представлений типов для дискретных типов, перечисленных в Ada LRM 12.5.2.

Например:

generic

   type Type_Element_Discrete is (<>);
   type Type_Element_Signed_Int is range <>;
   type Type_Element_Mod is mod <>;
   type Type_Element_Digits is digits <>;
   type Type_Element_Delta is delta <>;
   type Type_Element_Delta_Digits is delta <> digits <>;

package Gen_Convert is

   function Gen_Convert (Param_String : String) return Type_Element_Discrete;
   function Gen_Convert (Param_String : String) return Type_Element_Signed_Int;
   function Gen_Convert (Param_String : String) return Type_Element_Mod;
   function Gen_Convert (Param_String : String) return Type_Element_Digits;
   function Gen_Convert (Param_String : String) return Type_Element_Delta;
   function Gen_Convert (Param_String : String) return Type_Element_Delta_Digits;

end Gen_Convert;

Указание соответствующего формального типа также гарантирует, что создатель универсального объекта предоставляет допустимый тип. Вот соответствующее тело, демонстрирующее преобразование значений:

package body Gen_Convert is

   function Gen_Convert (Param_String : String) return Type_Element_Discrete is
   begin
      return Type_Element_Discrete'Value(Param_String);
   end Gen_Convert;

   function Gen_Convert (Param_String : String) return Type_Element_Signed_Int is
   begin
      return Type_Element_Signed_Int'Value(Param_String);
   end Gen_Convert;

   function Gen_Convert (Param_String : String) return Type_Element_Mod is
   begin
      return Type_Element_Mod'Value(Param_String);
   end Gen_Convert;

   function Gen_Convert (Param_String : String) return Type_Element_Digits is
   begin
      return Type_Element_Digits'Value(Param_String);
   end Gen_Convert;

   function Gen_Convert (Param_String : String) return Type_Element_Delta is
   begin
      return Type_Element_Delta'Value(Param_String);
   end Gen_Convert;

   function Gen_Convert (Param_String : String) return Type_Element_Delta_Digits is
   begin
      return Type_Element_Delta_Digits'Value(Param_String);
   end Gen_Convert;

end Gen_Convert;
person Marc C    schedule 09.04.2011
comment
Большое спасибо. Но моя проблема в том, что TypeElement может быть целым числом или строкой. Я должен установить тип как частный, чтобы сделать это, не так ли? - person Flatbeat; 09.04.2011
comment
Атрибут 'Value недействителен для Integer, поэтому невозможно создать универсальный объект, который будет полагаться на него для извлечения целочисленного значения из TypeElement. (И да, TypeElement должен быть закрытым формальным типом, чтобы принимать фактический тип Integer или String). Однако, если для универсального также требуется функция Value_Of: with Value_Of(T : TypeElement) return String, тогда создатель предоставит TypeElement и функцию Value_Of (которая может использовать 'Value), и ваш универсальный пакет просто вызовет Value_Of() для преобразования из строки в целое число или просто верните целое число. - person Marc C; 09.04.2011
comment
В приведенном выше комментарии я опечатался в возвращаемом типе предложенной функции Value_Of(), он должен быть: with Value_Of(T : TypeElement) return Integer. (Не хватило времени на редактирование комментария.) - person Marc C; 09.04.2011
comment
Также стоит проверить ваши типы с плавающей/фиксированной запятой на «valid», поскольку не все битовые шаблоны являются допустимыми числами с плавающей запятой. - person NWS; 11.04.2011
comment
Как правило, если кто-то не проголосовал за комментарий, я исправляю эту проблему, копируя текст комментария в буфер обмена, удаляя комментарий и затем повторно отправляя его (с исправлением). - person T.E.D.; 13.04.2011