Jump to content
lisichkin_alexander

Record operator overloading error

Recommended Posts

Happy New Year, everyone!

 

I create a class(record) with operator overloading.

But I got an error: [dcc32 Error] E2015 Operator not applicable to this operand type

Which operator did I forget to override?

 

uses
  System.SysUtils, System.Generics.Collections, System.Rtti, System.TypInfo;

type
  TplFilterValue<T> = record
    class operator Implicit(AValue: T): TplFilterValue<T>;
    class operator Implicit(AValue: TplFilterValue<T>): T;
    class operator LogicalNot(AValue: TplFilterValue<T>): Boolean;
    class operator LogicalOr(ALeft: TplFilterValue<T>; ARight: TplFilterValue<T>): Boolean;
    class operator LogicalAnd(ALeft: TplFilterValue<T>; ARight: TplFilterValue<T>): Boolean;
  private
    FValue: T;
    class function AsBoolean(AValue: TplFilterValue<T>): Boolean; static;
    procedure SetValue(AValue: T);
  public
    property Value: T read FValue write SetValue;
  end;
 
procedure TplFilterValue<T>.SetValue(AValue: T);
begin
  FValue := AValue;
end;

class operator TplFilterValue<T>.Implicit(AValue: T): TplFilterValue<T>;
begin
  Result.FValue := AValue;
end;

class operator TplFilterValue<T>.Implicit(AValue: TplFilterValue<T>): T;
begin
  Result := AValue.FValue;
end;

class function TplFilterValue<T>.AsBoolean(AValue: TplFilterValue<T>): Boolean;
var
  LTypeInfo: PTypeInfo;
  LValue: TValue;
begin
  LTypeInfo := System.TypeInfo(T);
  if LTypeInfo^.Name <> 'Boolean' then
    raise Exception.Create('Unsupported type operation');
  LValue := TValue.From<T>(AValue.FValue);
  Result := LValue.AsBoolean;
end;

class operator TplFilterValue<T>.LogicalNot(AValue: TplFilterValue<T>): Boolean;
begin
  Result := not AsBoolean(AValue);
end;

class operator TplFilterValue<T>.LogicalOr(ALeft: TplFilterValue<T>; ARight: TplFilterValue<T>): Boolean;
begin
  Result :=  AsBoolean(ALeft) or AsBoolean(ARight);
end;

class operator TplFilterValue<T>.LogicalAnd(ALeft: TplFilterValue<T>; ARight: TplFilterValue<T>): Boolean;
begin
  Result :=  AsBoolean(ALeft) and AsBoolean(ARight);
end;

var
  a: TplFilterValue<Boolean>;
begin
  try
    a := False;
    if not a then
      writeln('not a = True');
    if a or True then
      writeln('a or');
    if a and True then
      writeln('a and');
    if not(a) or True then   <<--- Error [dcc32 Error] E2015 Operator not applicable to this operand type
      writeln('a not or');
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

 

Edited by lisichkin_alexander

Share this post


Link to post

It compiles successfully if the error line is fixed like this:

 if (not a) or True then

or this (I do not know the original intent of the statement):

if not (a or True) then

 

Share this post


Link to post
16 hours ago, lisichkin_alexander said:

if not(a) or True then <<--- Error [dcc32 Error] E2015 Operator not applicable to this operand type writeln('a not or');

not(a) looks weird to me.

  • Like 1

Share this post


Link to post
Posted (edited)

Thanks for the help.
Yes, indeed the code:

if (not a) or True then

work.

But why code:

var
  b: boolean;
begin
  b := False;
  if not b or True then
    writeln('b not or');
end;

work

and code:

var
  a: TplFilterValue<Boolean>;
begin
  a := False;
  if not a or True then
    writeln('a not or');
end;

do not work?

I assumed that I did not override for some operator for the record 😕

 

P.S. I use Delphi 10.2, so I can not use operator assign

 

Edited by lisichkin_alexander
Mote info

Share this post


Link to post
3 hours ago, David Heffernan said:

I can't see why your code should fail. I suggest that you submit a bug report to Quality Portal.

 

3 hours ago, David Heffernan said:

This looks like a compiler bug to me.

 

Share this post


Link to post
Posted (edited)

Here's my 7 cents worth.  'Explicitly' use a's Value to remove need for braces.

var
  a: TplFilterValue<Boolean>;
  B: Boolean;
  procedure  //Boolean User output
    Bout (argS: string; aB: Boolean);
      begin
        writeln(argS + ' = ', aB);
      end;
  function
    NotFixup(aB: TplFilterValue<Boolean>): Boolean;
      begin
        Result := not aB.Value;
      end;

begin
  try
    a.Value := True;
    //if not a then
      Bout('not a', not a);
      Bout('a or True', a or True);
      Bout('a and True', a and True);

    Writeln('  NotFixup');
    //if not a or True then  // <<--- Error [dcc32 Error] E2015 Operator not applicable to this operand type
      Bout('Notfixup(a) or True', NotFixup(a) or True);
      Bout('NotFixup(a or True)', NotFixup(a or True));

    Writeln('  Precedence manual sort fix');
     // Bout('True or not (a)', True or not (a));
      Bout('True or not a', True or not a);

    Writeln('  not precedence working for boolean here');
      B := a;
      Bout('not B or True', not B or True);
      a := not B or True;
    Writeln('  Or use a''''s Value explicitly :)');

      Bout('not a.value or True', not a.value or True);

    readln;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

 

Edited by Pat Foley
add 2 lines to sample

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×