3

How can I properly use Anonymous Functions? I am trying use a generic compare function but I get the following error in the example bellow. Can someone explain why does this happen?

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.
5
  • 1
    FWIW, TArray.Sort<T> in Generics.Collections implements this already. And also, FWIW, your compare function is no good. Imagine what happens when L is high(Integer) and R is low(Integer). Commented Jun 25, 2014 at 12:57
  • @DavidHeffernan compare function can be anything thats the beauty of generics without any kind of interfaces. Commented Jun 25, 2014 at 13:01
  • 2
    You are reinventing things from System.Generics.Collections and System.Generics.Defaults. Commented Jun 25, 2014 at 13:31
  • 1
    You don't need to deal with any interfaces. You can just supply a compare function. And I don't call your compare function beautiful. I call it an overflow generator. Your entire code can be replaced by TArray.Sort<Integer>(A). If you want to supply a compare function you use TArray.Sort<Integer>(A, TComparer<Integer>.Construct(Comparison)) where Comparison is your anonymous method. Commented Jun 25, 2014 at 13:38
  • 3
    Also, +1 for a really good SSCCE with complete code and a full error message. Commented Jun 25, 2014 at 13:42

1 Answer 1

2

I think that you should actually want

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

or

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

instead of

I := Compare(1, 2);

As TLama already mentioned: Compare expects two parameters of type T. A is an array of T, so you can supply its members. 1 and 2 however are integers.

The fact that you later on say that you want T to be an integer is not relevant at this point: If you can say at this point that your code ALWAYS will use integer as T, then you shouldn't use a generic

Sign up to request clarification or add additional context in comments.

2 Comments

T will be anything not just an Integer.
@user3764855 Thought so (otherwise using a generic wouldn't make sense). So in that case Compare(1, 2) is definitely wrong.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.