Как привести указатель к универсальному типу параметра? - PullRequest
5 голосов
/ 04 февраля 2009

это мой первый вопрос здесь, рад, что нашел этот сайт.

Мой вопрос касается новой функции Generics в Delphi 2009. По сути, я попытался написать универсальный класс-оболочку для существующей реализации хэш-карты. Существующая реализация хранит пары (String, Pointer), поэтому в классе-оболочке мне приходится приводить между общим типом параметра T и типом Pointer и наоборот.

type THashMap <T : class> = class
private
  FHashList   : THashList;
  ...

end;

Я думал о таком броске (Значение: T)

Value := (TObject (Ptr)) as T

Но это не работает. Компилятор говорит мне: «Оператор не применим к этому типу операнда».

У кого-нибудь есть намеки? Заранее большое спасибо.

Ответы [ 2 ]

10 голосов
/ 04 февраля 2009

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

PObject(@Value)^ := Ptr;

Причина, по которой вы не можете просто ввести значение типа T, где T неограничен, заключается в том, что компилятор не знает размер T; обычно нечисловые типы могут преобразовывать значения только в типы одинакового размера.

К сожалению, компилятор не настолько умен, чтобы понять, что ограничение типа класса означает, что T гарантированно будет того же размера, что и указатель.

Кроме того, существует проблема с текущими обобщениями Delphi 2009 с созданием указателей для типов параметров типов. Общие указатели не поддерживаются компилятором, но компилятор разрешает этот синтаксис внутри классов:

type
  C<T> = class
  type
    PT = ^T; // UNSUPPORTED!
  end;

Это может работать для определенных сценариев - и может быть полезно для вашей конкретной проблемы - но это работает только случайно и обычно не поддерживается. Используйте на свой страх и риск.

0 голосов
/ 04 февраля 2009

Попробуйте это:

Value := TObject (Ptr)

Нет необходимости разыгрывать больше, поскольку допустимо присвоение TObject универсальной переменной типа класса:)

Но я не знаю причину, по которой вы не можете использовать T для кастинга, во-первых ...

...