0

I have read how to make a pointer to a normal class and use it inside the class difinition:

type
  PExample = ^TExample;
  TExample = class
    data: Integer;
    next: PExample;
  end;

but how do you do it with templatized parameters? This does not compile with the error Undeclared identifier: 'TExample' on the second line:

type
 PExample = ^TExample;
 TExample<T> = class
   data: T;
   next: PExample;
 end;

Changing it to

PExample = ^TExample<T>;

does not fix it.

2
  • ^TExample<T> is a double pointer, it's a pointer to a pointer to an instance of an object. Commented Mar 18, 2011 at 6:44
  • You could consider making a generic LinkedList class, so that you don't have to build the linked list functionality in every class. Commented Mar 18, 2011 at 7:48

3 Answers 3

4

As you are using a class, you don't need to use a PExample. Classes are already reference types.

 TExample<T> = class
   data: T;
   next: TExample<T>;
 end;

This should work without the need to declare any pointer types. Pointer types are only required if you work with records (which are value types).

EDIT:

To my surprise I just noticed that this compiles and works in Delphi XE:

program Project;

{$APPTYPE CONSOLE}

type
  TNode<T> = record
    Next: ^TNode<T>;
    Data: T;
  end;

var
  Node1, Node2: TNode<Integer>;

begin
  Node1.Next := @Node2;
  Node1.Data := 1;
  Node2.Next := nil;
  Node2.Data := 2;

  WriteLn(Node1.Data);
  WriteLn(Node1.Next.Data);
end.

It does still not solve the problem of defining a general generic pointer type, because this:

PNode<T> = ^TNode<T>;

does not work.

Sign up to request clarification or add additional context in comments.

5 Comments

I disagree with your last statement, so I keep the +1 for now, as pointers are "required" for other types, for instance, simple types like Integer, Double, etc.
It was not my intention of saying that generic pointers are generally not required. Not supporting them is a huge hole in Delphi's generic support. But in the context of the original question pointers are only required if you want to use records. They are not required if you use classes (which are already pointers).
What about simple types, like Integers?
@jachguate, What do you mean? I already said that generic pointer types in general should definitely be added. But again, this has nothing at all to do with the original question. The example given in the original question, the Questioner was trying to define a pointer to a class. In this context, pointers are not required because classes are already pointers (as my answer stated). You could define the same type of data structure (a single linked list) using records. In that case pointers would be required (as my answer stated)...
... You can not define a single linked lists using "simple types, like integers" which is why they have absolutely nothing, whatsoever, at all, to do with my answer.
2

The other answers tell you how to build a generic linked list of classes. If you ever need to build a generic linked list of records, you cannot do so at present:

type
  PNode<T> = ^TNode<T>;
  TNode<T> = record
  public
    Next: PNode;
  end;

does not compile.

Nor does:

type
  TNode<T> = record
  type
    PNode = ^TNode;
  public
    Next: PNode;
  end;

I believe that the reason for this is that the single-pass compiler does not support forward declarations of methods. This is actually more of a practical problem for operator overloading than for generics because classes can be used for generic linked lists.

9 Comments

That is not correct. In this case Next is a pointer to T, not to TNode<T> as it would need to be.. and there should be a Data: T; field. Unfortunately, the delphi compiler fails when trying to define "P = ^TNode<T>;". Clearly generics in Delphi are not yet ready for much more than playing around with and marvel at all the holes still left in their implementation.
@Thorsten Thanks. I'm doing a lot of learning in public today!! ;-) I think Delphi generics are fine for what they are, they are still very useful. They just don't have the flexibility of templates.
The limitations of generics in Delphi are not fundamental limitations of generics, they are simply the result of an half-baked implementation that was never properly finished. I've a rather large number of QC's logged against generics (and the new RTTI) in the hope that they are one day actually finished so far that it's actually possible to seriously use them.
@Thorsten Is that so. I'm making the distinction between generics and templates. For example I'd like to be able to write a generic method, DoSomething(const a, b: T): T; begin Result := a+b; end; and that can't be done with generics as implemented in Delphi, but can with templates. Can .net generics do what I want?
@David, yes, .NET supports what you describe: msdn.microsoft.com/en-us/library/ms172192.aspx#Y200
|
1

Is it necessary to use a pointer to a class? Using a class reference for your "next" field should work, like this:

type
 TExample<T> = class
   data: T;
   next: TExample<T>;
 end;

The "next" field can still be NIL or can be assigned another TExample instance. This seems to negate the need of using a traditional ^ pointer (although you could argue that a reference to a class is also a pointer, just with different syntax).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.