views:

196

answers:

2

Delphi 2006 introduced operator overloading which was then bugfixed in Delphi 2007. This is about Delphi 2007.

Why does the following not compile:

type
  TFirstRec = record
    // some stuff
  end;

type
  TSecondRec = record
    // some stuff
  end;

type
  TThirdRec = record
    // some stuff
    class operator Add(_a: TFirstRec; _b: TSecondRec): TThirdRec;
end;

class operator TThirdRec.Add(_a: TFirstRec; _b: TSecondRec): TThirdRec;
begin
   // code to initialize Result from the values of _a and _b
end;

var
  a: TFirstRec;
  b: TSecondRec;
  c: TThirdRec;
begin
  // initialize a and b

  c := a + b; // <== compile error: "Operator not applicable to this operand type"
end.

Since I have declared an operator that adds two operands a of type TFirstRec and b of type TSecondRec resulting in a TThirdRec, I would have expected this to compile.

(If you need something less abstract, think of TMyDate, TMyTime and TMyDateTime.)

+2  A: 

When I tried to compile the code in Delphi 2009 I have got the compiler error

[Pascal Error] Project1.dpr(21): E2518 Operator 'Add' must take least one 'TThirdRec' type in parameters

at line

class operator Add(_a: TFirstRec; _b: TSecondRec): TThirdRec;

so the answer is - at least one of the arguments (_a; _b) must be of type TThirdRec

Serg
Hm, yes, this sounds possible. Unfortunately, as gabr already mentioned, it is impossible to declare the operator in any other way because there is no forward declaration of records.So, which of these two answers do I accept? I guess, your's, because it answered the question. Thanks.
dummzeuch
It's not impossible, at least not with the declarations you've shown. Simply declare `TThirdRec` *first*, and then declare the `Add` operator in `TSecondRec`.
Rob Kennedy
Rob, this is a problem if you want Add operators to cover all possible combinations of those three records (which is a problem in itself as one would have to write 3x3x3 = 27 Add operators).
gabr
@rob: You are right, with the example this would be possible but the reason I declared them in that order is that the real world code this refers to already has got dependencies between these records.
dummzeuch
Actually, Gabr, you would only need 6 add operators. A+B, B+A, A+C, C+A, B+C, C+B.
Svein Bringsli
A+A=A, A+A=B, A+A=C, A+B=A, A+B=B ...
gabr
Does operator overloading support that? Could A+A sometimes result in A, sometimes in B and sometimes in C?
Svein Bringsli
+1  A: 

Serg is right. This does compile:

program Project51;

{$APPTYPE CONSOLE}

uses
  SysUtils;

type
  TThirdRec = record
    // some stuff
  end;

  TFirstRec = record
    // some stuff
  end;

  TSecondRec = record
    // some stuff
    class operator Add(_a: TFirstRec; _b: TSecondRec): TThirdRec;
  end;

class operator TSecondRec.Add(_a: TFirstRec; _b: TSecondRec): TThirdRec;
begin
   // code to initialize Result from the values of _a and _b
end;

var
  a: TFirstRec;
  b: TSecondRec;
  c: TThirdRec;
begin
  // initialize a and b

  c := a + b; // <== compile error: "Operator not applicable to this operand type"
end.

That can be a problem if you have to declare Add for all possible combinations of TFirstRec, TSecondRec and TThirdRec, as there is no forward declaration for records in Delphi.

gabr