[Lazarus] "global" operator overloading
Xiangrong Fang
xrfang at gmail.com
Tue Feb 26 15:30:32 CET 2013
Hi Sven,
My code below:
===============================================
program project1;
{$mode objfpc}{$H+}
{$MODESWITCH advancedrecords}
uses Classes;
type
TMyStringList = record
StringList: TStringList;
class operator <(s1, s2: TMyStringList): Boolean;
end;
class operator TMyStringList.<(s1, s2: TMyStringList): Boolean;
begin
Result := s1.StringList.Count < s2.StringList.Count;
end;
begin
end.
===============================================
generated these errors:
project1.lpr(9,20) Error: It is not possible to overload this operator.
Related overloadable operators (if any) are:
project1.lpr(9,21) Error: It is not possible to overload this operator.
Related overloadable operators (if any) are:
project1.lpr(9,53) Error: Impossible operator overload
project1.lpr(12,31) Error: method identifier expected
project1.lpr(1,1) Fatal: Compilation aborted
I am using Lazarus 1.0.6/FPC2.6.0-6 on Linux Mint 14/x86_64.
Sincerely,
Shannon
2013/2/26 Sven Barth <pascaldragon at googlemail.com>
> 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
>
> --
> ______________________________**_________________
> Lazarus mailing list
> Lazarus at lists.lazarus.**freepascal.org<Lazarus at lists.lazarus.freepascal.org>
> http://lists.lazarus.**freepascal.org/mailman/**listinfo/lazarus<http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus-ide.org/pipermail/lazarus/attachments/20130226/a43d7c3b/attachment-0003.html>
More information about the Lazarus
mailing list