Обобщения и указатели - PullRequest
1 голос
/ 12 марта 2020

У меня есть этот код для демонстрации вопроса:

type
  PData = ^TData;
  TData = record
    ...
  end;

TBaseList<T> = class
  FList: TList<T>;
  ...
end;

TDataList = class(TBaseList<TData>);
type
  TProcTData = reference to procedure(var AData: TData); 
  TProcPData = reference to procedure(AData: PData);
public
  procedure TestT(AIndex: Integer; AProcT: TProcTData);
  procedure TestP(AIndex: Integer; AProcP: TProcPData);
end;

// This works, but we have 2 memory copying here (to Data and from Data)
procedure TDataList.TestT(AIndex: Integer; AProcT: TProcTData);
var
  Data: TData;
begin
  Data := FList[Index];
  AProcT(Data);
  FList[Index] := Data;
end;

procedure TDataList.TestP(AIndex: Integer; AProcP: TProcPData);
var
  Data: PData;
begin
  // Does not work
  AProcP(@FList[Index]);
  // Does not work too
  Data := @FList[Index];
  AProcP(Data);
end;

Здесь вопрос: я могу использовать метод TestT, но не могу использовать метод TestP.

Возможно ли это сделать с помощью PData, чтобы уменьшить копирование данных в локальную переменную и из локальной переменной?

1 Ответ

3 голосов
/ 12 марта 2020

@FList[Index] никогда не будет вам полезен. Это возвращает адрес временной локальной переменной, используемой для размещения возвращаемого значения из свойства getter. Фактически, я думаю, что в современных версиях Delphi это не скомпилируется.

Вам необходим доступ к базовому массиву. Либо

@FList.List[Index]

, если вам нужен адрес элемента, либо просто

FList.List[Index]

, если вы передаете параметр var.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...