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
[email protected]
http://lists.lazarus.freepascal.org/mailman/listinfo/lazarus

Reply via email to