Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2013-09

Incompatible type for generics?

9 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Xiangrong Fang

Hi All,

I wrote a TTree generic class, the code is here:

https://github.com/xrfang/fpcollection/blob/master/src/units/tree.pas

While using this class, I encountered the following problem:

program project1;
{$mode objfpc}{$H+}
uses tree;
type
  TIntTree = class(specialize TTree<Integer>)
  end;
var
  ti : TIntTree;
begin
  ti := TIntTree.Create(1, nil);
  ti := ti.Next;  <-- error here
end.

The error message is:

Error: Incompatible types: got "TIntTree.TTree$LongInt" expected "TIntTree"

If I do not inherit TTree but just specialize it, there is no error.

How can I solve this problem so that I don' t have to use typecast everywhere?

Thanks,
Xiangrong

Reply by email

Sven Barth
to Xiangrong Fang
"Xiangrong Fang" wrote 25 lines
Hi All, I wrote a TTree generic class, the code is here: https://github.com/xrfang/fpcollection/blob/master/src/units/tree.pas While using this class, I encountered the following problem: program project1; {$mode objfpc}{$H+} uses tree; type TIntTree = class(specialize TTree<Integer>) end; var ti : TIntTree; begin ti := TIntTree.Create(1, nil); ti := ti.Next; <-- error here end. The error message is: Error: Incompatible types: got "TIntTree.TTree$LongInt" expected

"TIntTree"

If I do not inherit TTree but just specialize it, there is no error. How can I solve this problem so that I don' t have to use typecast

everywhere?

Short answer: you can't. The same would happen with normal classes.

Long answer: You could add an additional method "Next" to your "TIntTree" which returns a "TIntTree" and just do "Result := TIntTree(inherited Next);" there.

Why are you subclassing in this case anyway?

Regards,
Sven

Reply by email

Xiangrong Fang
to Sven Barth
Show quoted text 8 lines
Short answer: you can't. The same would happen with normal classes. Long answer: You could add an additional method "Next" to your "TIntTree" which returns a "TIntTree" and just do "Result := TIntTree(inherited Next);" there. Why are you subclassing in this case anyway?

Thanks, I will inherit the method. I need to add features in the sub-class. This empty TIntTree is just to show the problem.

Reply by email

Xiangrong Fang
to Xiangrong Fang

Hi Sven,

2013/9/23 Xiangrong Fang

Show quoted text 7 lines
Short answer: you can't. The same would happen with normal classes. > > Long answer: You could add an additional method "Next" to your "TIntTree" > which returns a "TIntTree" and just do "Result := TIntTree(inherited > Next);" there. > I still have problem with this strange issue. See the demo program below:
program test;
{$mode objfpc}{$H+}
uses treap;
type
  TStringMapper = class(specialize TTreap<string, string>)
  end;
var
  sm1, sm2: TStringMapper;
  n: TStringMapper.PNode;
begin
  sm1 := TStringMapper.Create;
  for n in sm1.Reversed do WriteLn(n^.Key);   <-- but NOT here
  sm2 := sm1.Reversed;                        <-- error here
end.

Why is this? Also, I found that the keyword "specialize" is recognized in fpc mode, but "class" is only valid in objfpc mode, is that correct?

Regards,
Xiangrong

Reply by email

Sven Barth
to Xiangrong Fang
Xiangrong Fang wrote 28 lines
Hi Sven, 2013/9/23 Xiangrong Fang < > Short answer: you can't. The same would happen with normal classes. Long answer: You could add an additional method "Next" to your "TIntTree" which returns a "TIntTree" and just do "Result := TIntTree(inherited Next);" there. I still have problem with this strange issue. See the demo program below: program test; {$mode objfpc}{$H+} uses treap; type TStringMapper = class(specialize TTreap<string, string>) end; var sm1, sm2: TStringMapper; n: TStringMapper.PNode; begin sm1 := TStringMapper.Create; for n in sm1.Reversed do WriteLn(n^.Key); <-- but NOT here sm2 := sm1.Reversed; <-- error here end.

How is PNode declared? What is the exact error?

Why is this? Also, I found that the keyword "specialize" is recognized in fpc mode, but "class" is only valid in objfpc mode, is that correct?

"specialize" is used in all modes except mode Delphi for specializations. "class" is available in all modes except "iso", "tp" and "fpc", but can be enabled there using {$modeswitch class}.

Regards,
Sven

Reply by email

Sven Barth
to Xiangrong Fang
Xiangrong Fang wrote 14 lines
2013/9/24 Sven Barth < > How is PNode declared? What is the exact error? PNode is declared inside TTreap generic class, the source is here: https://github.com/xrfang/fpcollection/blob/master/src/units/treap.pas The exact error is: Error: Incompatible types: got "TStringMapper.TTreap$AnsiString$AnsiString" expected "TStringMapper"

The error is exactly the same as the one in your TIntTree, because the return type of TTreap<String, String>.Reversed is TTreap<String, String> and nothing else. Thus the solution is the same as for TIntTree.Next: either none or a new "Reversed" function. And again: This problem would also occur with non generic classes.

Regards,
Sven

Reply by email

Xiangrong Fang
to Sven Barth

I know it is same but why no error on the line:

for n in sm1.reversed...

regards.
在 2013-9-24 下午11:23,"Sven Barth" 写道:

Show quoted text 30 lines
Am 24.09.2013 17:14, schrieb Xiangrong Fang: 2013/9/24 Sven Barth > How is PNode declared? What is the exact error? > > PNode is declared inside TTreap generic class, the source is here: https://github.com/xrfang/fpcollection/blob/master/src/units/treap.pas The exact error is: Error: Incompatible types: got "TStringMapper.TTreap$AnsiString$AnsiString" expected "TStringMapper" The error is exactly the same as the one in your TIntTree, because the return type of TTreap<String, String>.Reversed is TTreap<String, String> and nothing else. Thus the solution is the same as for TIntTree.Next: either none or a new "Reversed" function. And again: This problem would also occur with non generic classes. Regards, Sven _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply by email

Sven Barth
to Xiangrong Fang
Xiangrong Fang wrote 5 lines
I know it is same but why no error on the line: for n in sm1.reversed...

n is of type TStringMapper.PNode whereby PNode is declared inside TTreap<String, String> and thus the type is in reality a TTreap<String, String>.
sm1.reversed returns a TTreap<String, String> which has an enumerator that works on a TTreap<String, String>.PNode. So everything is well.

Regards,
Sven

Reply by email