[fpc-pascal] Generics - extending TFPGObjectList

Sven Barth pascaldragon at googlemail.com
Thu Jul 26 07:04:42 CEST 2018


Am 26.07.2018 um 02:31 schrieb Vojtěch Čihák:
>
> Hello,
>
> I needed to extend TFPGObjectList and I found two wierd things (FPC 
> 3.1.1 r39507):
>
> program project1;
>
> {$mode objfpc}{$H+}
>
> uses
>
>   Classes, FGL;
>
> type
>
>   TBaseClass = class (TObject)
>
>   end;
>
>   TIDClass = class (TBaseClass)
>
>     ID: Integer;
>
>   end;
>
>   TNameIDClass = class (TIDClass)
>
>     Name: string;
>
>   end;
>
>   generic TFPGObjectListEx<T: TIDClass> = class (specialize 
> TFPGObjectList<TBaseClass>) //1 A
>
>     function GetItemByID(AID: Integer): T;
>
>   end;
>
>   TNameIDList = class (specialize TFPGObjectListEx<TNameIDClass>)
>
>   end;
>
> {$R *.res}
>
> function TFPGObjectListEx.GetItemByID(AID: Integer): T;
>
> begin
>
>   {...}
>
>   Result:=nil; //2
>
> end;
>
> var NameIDList: TNameIDList;
>
>     NameID: TNameIDClass;
>
> begin
>
> NameID:=NameIDList.Items[0]; //1 B
>
> end.
>
> The demo does not compile because of two errors:
>
> 1) project1.lpr(38,21) Error: Incompatible types: got "TBaseClass" 
> expected "TNameIDClass" at comment //1 B
>
> It is caused by declaration at //1 A. Class TFPGObjectListEx can be 
> really generic only if it is declared like this:
>
>    generic TFPGObjectListEx<T: TIDClass> = class (specialize 
> TFPGObjectList<T>) //1 A, otherwise you must retype 
> TNameIDClass(Items[0]) and it is against the philosophy of generics. 
> Isn't it meaningless? Why there must be specialize to <T> when in fact 
> it is no specialization at all.
>

You are not overriding the Items property, thus it will still be the 
Items property of TFPGObjectList<TBaseClass> and thus the compiler will 
rightfully complain at location 1 B. Using generics does not absolve you 
from usual inheritance problems.

> 2) project1.lpr(32,11) Error: Incompatible types: got "Pointer" 
> expected "$gendef4" at comment //2
>
> The line must be changed to
>
>   Result:=T(nil);
>
> which seems bizarre to me, I've never seen retyping "nil". Even more, 
> both TFPGObjectList and TFPGObjectListEx are constrained to TObject 
> and to TIDClass so there is safety, TFPGObjectListEx can be only 
> specialized with types that have "nil" (<T> can never be <Integer>, 
> for example).
>
Well, no one said that the generics are completely bug free... 
Especially in special situations that involve either Nil or type 
constraints (or in this case both). Please provide a simple example and 
open a bug report.

Regards,
Sven
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freepascal.org/pipermail/fpc-pascal/attachments/20180726/588e006d/attachment.html>


More information about the fpc-pascal mailing list