[Lazarus] "global" operator overloading
Sven Barth
pascaldragon at googlemail.com
Tue Feb 26 15:00:59 CET 2013
On 26.02.2013 09:36, Xiangrong Fang wrote:
> Hi Sven,
>
> Could you please give a simple example that shows what you said: require
> that the type with which you specialize is a record. Then a class
> operator in that record can be defined.
Let's suppose you have the following generic declaration:
=== example begin ===
type
generic TTreap<T1, T2> = class
// let's assume T1 requires "<"
end;
=== example end ===
If you use a record to specialize TTreap's T1 parameter then you can do
it the following way:
=== example begin ===
type
TMyRecord = record
// note: in mode objfpc the modeswitch advancedrecords is needed
class operator < (aLeft, aRight: TMyRecord): Boolean;
end;
// implementation:
class operator TMyRecord.<(aLeft, aRight: TMyRecord): Boolean;
begin
// compare aLeft and aRight
end;
// somewhere else
TTreapTMyRecordLongInt = specialize TTreap<TMyRecord, LongInt>;
=== example end ===
Now the generic will specialize without problem. If you want to
specialize other types that don't support class operators then you need
to wrap them inside a record, e.g.:
=== example begin ===
type
TRecTStringList = record
MyStringList: TStringList;
class operator < (aLeft, aRight: TRecTStringList): Boolean;
end;
=== example end ===
You can also use visibility modifiers like private or strict private to
hide the MyStringList field and make it accessible only through
properties. To simplyfy usage you can also define assignment operators.
E.g.:
=== example begin ===
type
// maybe it will also work with a TStringList if you use TStrings
instead...
TRecTStringList = record
private
fStringList: TStringList;
public
class operator := (aRight: TStringList): TRecTStringList;
class operator := (aRight: TRecStringList): TStringList;
end;
class operator TRecTStringList.:=(aRight: TStringList): TRecTStringList;
begin
Result.fStringList := aRight;
end;
class operator TRecTStringList.:=(aRight: TRecStringList): TStringList;
begin
Result := aRight.fStringList;
end;
// somewhere else:
var
sl: TStringList;
rec: TRecStringList;
begin
// setup sl
rec := sl;
// use rec in the tree
sl := rec;
end;
=== example end ===
It's not the nicest solution, but currently the only thing you can do.
Regards,
Sven
More information about the Lazarus
mailing list