Reputation: 2043
here come my definition of Vertex class and graph class using generic programming features of Delphi :
unit Unit1;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs,
System.Math, System.Generics.Collections,
System.Generics.Defaults, Vcl.StdCtrls;
type
tvertex = class(TObject)
name: string;
function markme: tvertex;
function Compare(const v: TVertex): Integer;
constructor create;
destructor free;
end;
tvertex<T> = class(tvertex)
Userdata: T;
end;
TGraph <T : class > = class (Tobject)
vertexlist : TObjectList<T>;
procedure CompareLists(
var _V1: TObjectList<T>;
var _V2: TObjectList<T>);
end;
TForm1 = class(TForm)
Edit1: TEdit;
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;
var
Form1: TForm1;
// helper function
function createVertexComparer(): IComparer <TVertex >;
implementation
// helper functions
function createVertexComparer(): IComparer<TVertex>;
begin
Result := TDelegatedComparer<TVertex>.Create(
function(const Left, Right: TVertex): Integer
begin
Result := Left.Compare(Right);
end);
end;
{$R *.dfm}
{ tvertex }
function tvertex.Compare(const v: TVertex): Integer;
begin
// ...
end;
constructor tvertex.create;
begin
// ...
end;
destructor tvertex.free;
begin
// ...
end;
function tvertex.markme: tvertex;
begin
// ...
end;
procedure TGraph<T>.CompareLists(
var _V1: TObjectList<T>;
var _V2: TObjectList<T>);
begin
_V1 := TObjectList<T>.Create(createVertexComparer(), False); /// line which does not compile ....
end;
end.
How to modify the code that he is willing to accept TVertex
and TVertex<T>
class types as arguments ....
Upvotes: 0
Views: 1020
Reputation: 612993
I would say that the main problem that you have is that you declared the graph class like this:
type
TGraph<T: class>
...
end;
And this means that the compiler will accept any class as T
. Consequently the graph class knows nothing about T
, beyond that it is a class.
It's hard to be sure, but I think that you intend T
to be a vertex. So you need to constraint the graph class appropriately.
type
TGraph<T: TVertex>
...
end;
And then you have another problem with this function:
function createVertexComparer(): IComparer<TVertex>;
You pass the result of that to
TObjectList<T>.Create
But that expects a parameter of type IComparer<T>
and you are supplying IComparer<TVertex>
. That's the type mismatch that the compiler reports.
You'll need to make createVertexComparer
be a method of TGraph<T>
so that it can be generic. Its implementation would be:
function TGraph<T>.createVertexComparer(): IComparer<T>;
begin
Result := TDelegatedComparer<T>.Create(
function(const Left, Right: T): Integer
begin
Result := Left.Compare(Right);
end);
end;
Also, do note that
destructor free;
is a disaster waiting to happen. You must use
destructor Destroy; override;
In fact, the rest of your code troubles me. For instance:
procedure TGraph<T>.CompareLists(var _V1, _V2: TObjectList<T>);
begin
_V1 := TObjectList<T>.Create(createVertexComparer(), False);
end;
The method's name does not match what it does. It only returns one value, so why have two var
parameters? It's very hard to discern intent when viewing code like this.
Upvotes: 2