On 18/02/2021 22:42, Sven Barth wrote:

You need to constrain T as a TObject, then it works.

Ah that works. With 2 restrictions

TBase can be any class, since a trait can be applied to any class.
So the only known common base is TObject.

(restriction 1)
But "TBase: TObject" means that the trait can not access Self.Base, even if the latter passed in type has such a method.
Same with (note the "class" keyword)
     generic TTrait<TBase: class; THost> = class(TBase)


Normally if the param to a generic is not restricted you can write T.anything, and during specialization this will be resolved or fail.
So that ability is lost.

As a workaround THost can be passed in.
(restriction 2)
That requires a forward declaration of TFoo. Otherwise it fails.


type
  TFooBase = class
    procedure Base;
  end;

  generic TTrait<TBase: TObject; THost> = class(TBase)
    procedure Bar;
  end;

  TMyFoo = class;
  TMyFoo = class(specialize TTrait<TFooBase, TMyFoo>)
     procedure Foo;
  end;


procedure TTrait.Bar;
begin
  //Self.Base; // fails
  THost(Self).Base;
  THost(Self).Foo;
end;

_______________________________________________
fpc-pascal maillist  -  fpc-pascal@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal

Reply via email to