8.9 Operator overloading and generics

Operator overloading (chapter 15, page 855) and generics are closely related. Imagine a generic class that has the following definition:

{$mode objfpc}
unit mya;

interface

type
  Generic TMyClass<T> = Class(TObject)
    Function Add(A,B : T) : T;
  end;

Implementation

Function TMyClass.Add(A,B : T) : T;

begin
  Result:=A+B;
end;

end.

When the compiler replays the generics macro, the addition must be possible. For a specialization like this:

TMyIntegerClass = specialize TMyClass<integer>;

This is not a problem, as the Add method would become:

Procedure TMyIntegerClass.Add(A,B : Integer) : Integer;

begin
  Result:=A+B;
end;

The compiler knows how to add two integers, so this code will compile without problems. But the following code:

Type
  TComplex = record
   Re,Im : Double;
  end;

Type
  TMyIntegerClass = specialize TMyClass<TComplex>;

Will not compile, unless the addition of two TComplex types is defined. This can be done using record operators:

{$modeswitch advancedrecords}
uses mya;

Type
  TComplex = record
     Re,Im : Double;
     class operator +(a,b : TComplex) : TComplex;
  end;

class operator TComplex.+ (a,b : TComplex) : TComplex;

begin
  Result.re:=A.re+B.re;
  Result.im:=A.im+B.im;
end;


Type
  TMyComplexClass = specialize TMyClass<TComplex>;

begin
  // Code here
end.

Currently, due to an implementation restriction, it will not work using a global operator, i. e. the following does not work yet:

uses mya;

Type
  TComplex = record
     Re,Im : Double;
  end;

operator + (a,b : TComplex) : TComplex;

begin
  Result.re:=A.re+B.re;
  Result.im:=A.im+B.im;
end;

Type
  TMyComplexClass = specialize TMyClass<TComplex>;

begin
  // Code here
end.

Support for this construct is expected in a future version of Free Pascal.