Как использовать анонимные функции?

Как я могу правильно использовать анонимные функции? Я пытаюсь использовать общую функцию сравнения, но получаю следующую ошибку в приведенном ниже примере. Может кто-нибудь объяснить, почему это происходит?

program Project11;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  System.SysUtils,
  System.Classes;

type
  TSort<T> = record
  private
    type
      TCompare = reference to function(const L, R: T): Integer;
  public
    class procedure Sort(var A: Array of T; const First, Last: Integer; const Compare: TCompare); static;
  end;

{ TSort<T> }

class procedure TSort<T>.Sort(var A: array of T; const First, Last: Integer; const Compare: TCompare);
var
  I: Integer;
begin
  I := Compare(1, 2); // [dcc32 Error] Project11.dpr(30): E2010 Incompatible types: 'T' and 'Integer'
end;

var
  A: Array of Integer;
begin
  TSort<Integer>.Sort(A, 1, 2,
  function(const L, R: Integer): Integer
  begin
    // Do something with L & R
  end);
end.

person user3764855    schedule 25.06.2014    source источник
comment
FWIW, TArray.Sort<T> в Generics.Collections это уже реализовано. И еще, FWIW, твоя функция сравнения никуда не годится. Представьте, что произойдет, если L станет high(Integer), а R станет low(Integer).   -  person David Heffernan    schedule 25.06.2014
comment
Функция сравнения @DavidHeffernan может быть чем угодно, в чем прелесть дженериков без каких-либо интерфейсов.   -  person user3764855    schedule 25.06.2014
comment
Вы заново изобретаете вещи из System.Generics.Collections и System.Generics.Defaults.   -  person Stefan Glienke    schedule 25.06.2014
comment
Вам не нужно иметь дело с какими-либо интерфейсами. Вы можете просто предоставить функцию сравнения. И я не называю вашу функцию сравнения красивой. Я называю это генератором переполнения. Весь ваш код можно заменить на TArray.Sort<Integer>(A). Если вы хотите предоставить функцию сравнения, вы используете TArray.Sort<Integer>(A, TComparer<Integer>.Construct(Comparison)), где Comparison — ваш анонимный метод.   -  person David Heffernan    schedule 25.06.2014
comment
Кроме того, +1 за действительно хороший SSCCE с полным кодом и полным сообщением об ошибке.   -  person David Heffernan    schedule 25.06.2014


Ответы (1)


Я думаю, что вы действительно должны хотеть

I := Compare(A[1], A[2]);

or

I := Compare(A[First], A[Last]);

вместо

I := Compare(1, 2);

Как уже упоминал TLama: Compare ожидает два параметра типа T. A — это массив T, поэтому вы можете указать его члены. Однако 1 и 2 являются целыми числами.

Тот факт, что позже вы говорите, что хотите, чтобы T было целым числом, не имеет отношения к этому моменту: если вы можете сказать, что ваш код ВСЕГДА будет использовать целое число как T, то вам не следует использовать общий

person Daniel    schedule 25.06.2014
comment
T будет чем угодно, не только целым числом. - person user3764855; 25.06.2014
comment
@user3764855 user3764855 Так и думал (иначе использование универсального не имело бы смысла). Так что в этом случае Compare(1, 2) определенно неправ. - person Daniel; 25.06.2014