8.9 Operator overloading and generics

Operator overloading (chapter 15, page 768) 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 2 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 2 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.