[Lazarus] Error: Generics without specialization cannot be used as a type for a variable

Hans-Peter Diettrich DrDiettrich1 at aol.com
Tue May 10 23:19:57 CEST 2011


Peter Williams schrieb:

>  >The reason why I am choosing a Generic or Specialize is so that I have 
> accept to the 
> "Sort" procedure of TList. I am not sure if I am doing this correctly.

The Sort method requires a user-supplied *compare function*. Only that 
function must know about the type and contents of the list elements. In 
the implementation of that function you cast the given pointers into the 
real type of the list elements. That's all, no generics needed at all.

Generics are nice when you want to implement lists, which only accept 
elements of one specific type. Have a look at the Contnrs unit, that 
defines several descendants of TList. E.g. a TObjectList only accepts 
TObject items, a TComponentList only accepts TComponent items.

Take e.g. a TObjectList, and replace all occurences of "TObject" by 
"<T>", to make it a generic class:

TMyList<T> = class(TList)
...
   function Add(AObject: <T>): Integer;
...
end;

Now you can create your own TComponentList like TMyList<TComponent>.

Please find out the exact syntax yourself, I never used generics in Lazarus.


Sorting such a list looks more complicated to me - but perhaps I'm 
wrong. The simple approach would look like:

Add a generic Compare function:
   TMyCompare<T> = function(Item1, Item2: <T>): integer;
and in TMyList<T> add:
   procedure Sort(Compare: TMyCompare<T>);
and implement it to call the TList.Sort method:
   inherited Sort(TListCompare(Compare));

This should result in an error message, because the TListCompare 
function has Pointers as arguments, while the specialized function has 
<T> type arguments. The next step were an adaptation of the Sort method, 
copied from TList, so that the TMyList.Sort procedure calls the 
specialized Compare:TMyCompare<T> function.

DoDi





More information about the Lazarus mailing list