views:

421

answers:

2

I am using the operator overloading for records in Delphi 2006. (Please don't answer this question by telling me not to.)

I have two record types with the implicit operator overloaded. They are both only in the implementation of the module, not exposed through the interface.

My problem is, now that they are mutally dependent, I don't know how to forward declare the second type to the compiler. I know how to do this with functions, procedure and classes, but not with records.

Here is a simplified example of what I am trying to do:

implementation

type
  TMyRec1 = record
    Field1 : Integer;
    class operator Implicit(a: TMyRec2): TMyRec1;  // <---- Undeclared Identifier here.
  end;

  TMyRec2 = record
    Field2: Integer;
    class operator Implicit(a: TMyRec1): TMyRec2;
  end;

class operator TMyRec1.Implicit(a:TMyRec2): TMyRec1;
begin
  Result.Field1 := a.Field2;
end;

class operator TMyRec2.Implicit(a:TMyRec2): TMyRec2;
begin
  Result.Field2 := a.Field1;
end;
+6  A: 

You can't have forward declarations for record types. Define both Implicit operators in the second type:

type
  TMyRec1 = record
    Field1 : Integer;
  end;

  TMyRec2 = record
    Field2: Integer;
    class operator Implicit(a: TMyRec2): TMyRec1;
    class operator Implicit(a: TMyRec1): TMyRec2;
  end;

Quoting from the help:

Implicit conversions should be provided only where absolutely necessary, and reflexivity should be avoided. It is best to let type B implicitly convert itself to type A, and let type A have no knowledge of type B (or vice versa).

Rob Kennedy
Thanks Rob. Obvious solution I guess, but they all are when you know. Why do you say that implicit conversion should be avoided?
Richard A
*I* didn't say it should be avoided. I was quoting the documentation. But since you asked, implicit conversion can make code harder to read; it's harder to notice a conversion occurring when there's nothing calling any attention to it. I'd just use an ordinary function to convert from one type to another. Or you could use operator Explicit instead.
Rob Kennedy
Thanks. I should read more carefully. I skimmed the bit that says 'quoting from the help'. Yes, I'm a bit nervous about operator overloading and implicit conversions too, but trying it out in a small case to see how it goes. Funnily, some major performance problems I have had to fix have been with implicit conversion of standard numeric and string types.
Richard A
Sorry, is it just me or is it Opera putting huge blank spaces after my comments?
Richard A
Just you :)Opera is not putting huge blank spaces after _my_ comments.
gabr
A: 

How to SOLVE this problem:

unit myMath;

interface


type

  myInteger=record
    Value:string;
    class operator Implicit(s:string):myInteger; overload;
    class operator Implicit(i:integer):myInteger; overload;
  end;

  myFraction=record
    Nominator,Denominator:myinteger;
    class operator Implicit(m:myInteger):myFraction;
    class operator Divide(n,d:myInteger):myFraction;
  end;


implementation

class operator myInteger.Implicit(s:string):myInteger;
begin
  Result.Value:=s;
end;

class operator myInteger.Implicit(i:integer):myInteger;
begin
  str(i,Result.Value);
end;



class operator myFraction.Implicit(m:myInteger):myFraction;
begin
  Result.Nominator:=m;
  Result.Denominator:=1;
end;

class operator myFraction.Divide(n,d:myInteger):myFraction;
begin
  Result.Nominator:=n;
  Result.Denominator:=d;
end;


end.
Srba
Hi.First of all, create a question of your own. Second, your problem is that the Divide operator requires one of the parameters to be of the myFraction type. Possible: You can just accept only an myfraction with Denominator of 1 in code. If your reputation >1 I would downvote, but that indicates you're newbie on StackOverflow - so welcome.
Fabricio Araujo