views:

1213

answers:

2

Hello everybody, it's my first question here, glad to have found this site.

My question deals with the new Generics feature in Delphi 2009. Basically I tried to write a generic wrapper class for an existing hash map implementation. The existing implementation stores (String, Pointer) pairs, so in the wrapper class I have to cast between the generic parameter type T and the Pointer type and vice versa.

type THashMap <T : class> = class
private
  FHashList   : THashList;
  ...

end;

I thought of a cast like this (Value : T)

Value := (TObject (Ptr)) as T

But this doesn't work. The compiler tells me 'Operator not applicable to this operand type'.

Somebody has some hints? Thanks a lot in advance.

A: 

Try this:

Value := TObject (Ptr)

No need to cast more, as assigning the TObject to the generic class type variable is valid :)

But I do not know the reason why you cannot use T for casting in the first place...

Heinrich Ulbricht
+7  A: 

You need to take the address of the location of the generic type parameter type, then typecast this address to a pointer to the desired type, and then dereference this pointer and assign into the resulting location. For example:

PObject(@Value)^ := Ptr;

The reason you can't just typecast a value of type T, where T is unconstrained, is that the compiler doesn't know the size of T; normally, non-numeric typecasts can only convert values into types that are of the same size.

Unfortunately, the compiler is not smart enough to figure out that a class-type constraint means that T is guaranteed to be the same size as a pointer.

Also, there is an issue with current Delphi 2009 generics with creating pointers to type parameter types. Generic pointers are not supported by the compiler, but the compiler permits this syntax inside classes:

type
  C<T> = class
  type
    PT = ^T; // UNSUPPORTED!
  end;

This may work for certain scenarios - and can be helpful for your specific problem - but it only works by accident and is not generally supported. Use at your own risk.

Barry Kelly