Hello,
I get this error when I compile the following code in OBJFPC mode:
main2.pas(60,21) Fatal: Syntax error, "<" expected but "." found
Fatal: Compilation aborted
In DELPHI mode everything works though.
Is this behavior normal? I cannot use generic methods of a non-generic class in OBJFPC mode or has this been fixed in later versions of the FPC compiler?
Compiler version and target OS:
Free Pascal Compiler version 3.2.2 [2021/05/16] for aarch64
Copyright (c) 1993-2021 by Florian Klaempfl and others
Target OS: Darwin for AArch64
{$MODE OBJFPC}
program main2;
uses
fgl, typinfo;
type
IRepository = interface
['{8354082d-9ed9-41f7-86ec-2820cc925cd7}']
end;
TRepositoryA = class(TInterfacedObject, IRepository)
public
function tostring(): AnsiString; override;
end;
TRepositoryB = class(TInterfacedObject, IRepository)
public
function tostring(): AnsiString; override;
end;
TObjectMap = specialize TFPGMap<ShortString, IRepository>;
TFactory = class(TObject)
private
_objects: TObjectMap;
public
constructor create;
generic procedure register<T: class>;
generic function get<T: class>: T;
end;
constructor TFactory.create;
begin
_objects := TObjectMap.create;
inherited create;
end;
generic procedure TFactory.register<T>;
var
type_info: PTypeInfo;
type_name: ShortString;
begin
type_info := typeinfo(T);
type_name := type_info^.name;
_objects.add(type_name, T.create);
end;
generic function TFactory.get<T>: T;
var
type_info: PTypeInfo;
type_name: ShortString;
begin
type_info := typeinfo(T);
type_name := type_info^.name;
result := T(_objects[type_name]);
end;
function TRepositoryA.tostring(): AnsiString;
begin
result := 'Repository A';
end;
function TRepositoryB.tostring(): AnsiString;
begin
result := 'Repository B';
end;
var
factory: TFactory;
repo_a: TRepositoryA;
repo_b: TRepositoryB;
begin
factory := TFactory.create;
specialize factory.register<TRepositoryA>;
specialize factory.register<TRepositoryB>;
repo_a := specialize factory.get<TRepositoryA>;
repo_b := specialize factory.get<TRepositoryB>;
writeln(repo_a.tostring);
writeln(repo_b.tostring);
end.
{$MODE DELPHI}
program main2;
uses
fgl, typinfo;
type
IRepository = interface
['{8354082d-9ed9-41f7-86ec-2820cc925cd7}']
end;
TRepositoryA = class(TInterfacedObject, IRepository)
public
function tostring(): AnsiString; override;
end;
TRepositoryB = class(TInterfacedObject, IRepository)
public
function tostring(): AnsiString; override;
end;
TObjectMap = TFPGMap<ShortString, IRepository>;
TFactory = class(TObject)
private
_objects: TObjectMap;
public
constructor create;
procedure register<T: class>;
function get<T: class>: T;
end;
constructor TFactory.create;
begin
_objects := TObjectMap.create;
inherited create;
end;
procedure TFactory.register<T>;
var
type_info: PTypeInfo;
type_name: ShortString;
begin
type_info := typeinfo(T);
type_name := type_info^.name;
_objects.add(type_name, T.create);
end;
function TFactory.get<T>: T;
var
type_info: PTypeInfo;
type_name: ShortString;
begin
type_info := typeinfo(T);
type_name := type_info^.name;
result := _objects[type_name] as T;
end;
function TRepositoryA.tostring(): AnsiString;
begin
result := 'Repository A';
end;
function TRepositoryB.tostring(): AnsiString;
begin
result := 'Repository B';
end;
var
factory: TFactory;
repo_a: TRepositoryA;
repo_b: TRepositoryB;
begin
factory := TFactory.create;
factory.register<TRepositoryA>;
factory.register<TRepositoryB>;
repo_a := factory.get<TRepositoryA>;
repo_b := factory.get<TRepositoryB>;
writeln(repo_a.tostring);
writeln(repo_b.tostring);
end.