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

#ada

#ada

Вопрос:

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

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

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

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

Ошибка заключается в том, что «префикс атрибута «value» должен быть скалярного типа»

Есть ли какой-то трюк?

Ответ №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;
  

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

 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;
  

Комментарии:

1. Большое спасибо. Но моя проблема в том, что TypeElement может быть целым числом или строкой. Для этого я должен установить тип в private, нет?

2. Атрибут ‘Value недопустим для целого числа, поэтому нет способа создать универсальный инструмент, который будет полагаться на это для извлечения целочисленного значения из TypeElement. (И да, TypeElement должен быть частным формальным типом, чтобы принимать фактический тип Integer или String). Однако, если универсальному также требуется функция «Value_Of»: «with Value_Of(T : TypeElement) return String», то инстанциатор предоставит TypeElement и функцию Value_Of (которая может использовать ‘Value), и ваш универсальный пакет просто вызовет Value_Of() для преобразования из строки в целое число или просто вернет целое число.

3. В приведенном выше комментарии я неправильно ввел возвращаемый тип предлагаемой функции Value_Of(), он должен быть: with Value_Of(T : TypeElement) return Integer . (Закончилось время для редактирования комментария.)

4. Также стоит проверить ваши типы с плавающей / фиксированной запятой с помощью ‘valid поскольку не все битовые шаблоны являются допустимыми числами с плавающей запятой.

5. Как правило, если кто-то не проголосовал за комментарий «Против», я исправляю эту проблему, копируя текст комментария в буфер обмена, удаляя комментарий, а затем повторно отправляя его (с исправлением).