2

The Delphi TList.Sort() method expects a callback function argument of type function (Item1, Item2: Pointer): Integer; for comparing the list items.

I'd like to get rid of typecasting within the callback function and would like to define a callback function like this:

function MyTypeListSortCompare( Item1, Item2 : tMyType ) : integer;
begin
   result := WideCompareStr(Item1.Name, Item2.Name);
end;

...
MyList.Sort(tListSortCompare(MyTypeListSortCompare));
...

but unfortunately this triggers an "Invalid typecast" compiler error.

Is there some possibility to properly typecast function pointers in Delphi(2006)?

blerontin
  • 2,892
  • 5
  • 34
  • 60
  • No. That is not possible. Typecast items passed to that callback (callback must match its declaration). – Victoria Mar 21 '18 at 15:04
  • Of course not. But it makes no sense to want to do so. You write the sort procedure code one time, and never call it yourself. Why would you want to make it more difficult to read and maintain by adding a hackish typecast of the function? – Ken White Mar 21 '18 at 15:11
  • 1
    I used the Sort callback as an example, my question is not limited to sorting. – blerontin Mar 21 '18 at 15:25

2 Answers2

6

I normally do something like this:

function MyTypeListSortCompare( Item1, Item2 : Pointer ) : integer;
var
  LHS: TMyType absolute Item1;
  RHS: TMyType absolute Item2;
begin
  result := WideCompareStr(LHS.Name, RHS.Name);
end;
Keith Miller
  • 1,718
  • 1
  • 13
  • 22
  • I must ask, what `LHS` and `RHS` stands for? `L` and `R` is clear, but that `HS`? Just curious :) Btw. simple typecast like `WideCompareStr(TMyType(Item1).Name, TMyType(Item2).Name);` would do the same work here. – Victoria Mar 21 '18 at 17:40
  • 2
    @Victoria I guess Left Hand Side and Right Hand Side – Tom Brunberg Mar 21 '18 at 17:45
  • 1
    @Victoria But the functions kind of weighs, is whatever I have in my left hand heavier than the thing in the right, kind of ;) – Tom Brunberg Mar 21 '18 at 17:51
  • @Tom, `LHS` and `RHS` is from mathematics but in the end it's not bad naming. I'm using `A` and `B` even for callback parameters (instead of `1` and `2` postfix). – Victoria Mar 21 '18 at 18:00
  • @TomBrunberg left hand side and right hand side is correct. I dislike single character variable names so L and R are out. LHS and RHS are shorter than Left and Right :-) – Keith Miller Mar 21 '18 at 18:12
3

A typecast is possible but requires to prefix the function name with "@":

var
   MyList : TList;
begin
   ...
   MyList.Sort(TListSortCompare(@MyTypeListSortCompare));
   ...
end;

As pointed out in the comments the typecast isn't needed when type-checked pointers are turned off, so in that case this also works:

MyList.Sort(@MyTypeListSortCompare);
blerontin
  • 2,892
  • 5
  • 34
  • 60
  • 2
    cast is not needed. `MyList.Sort(@MyTypeListSortCompare);` works good – Fabrizio Mar 21 '18 at 15:26
  • 3
    "*the typecast actually isn't needed*" - only when [Type-checked pointers](http://docwiki.embarcadero.com/RADStudio/en/Type-checked_pointers_(Delphi)) is OFF, otherwise it is needed. – Remy Lebeau Mar 21 '18 at 15:50