I'm on D2010, on which I have to stay until the 64 bit comes out.
With the generics, pointers to generic types are not supported, and I would find them to be very useful indeed. I read elsewhere on SO (2009 posting) Sir Barry Kelly thought this may well change in future. Does anyone know if this is supported in XE?
If not, I really hope they get put into XE2.
Thanks.
On XE (2011):
This works:
type
TTest1<T> = record
FX : T;
end;
TTest2<T> = array of T;
This won't work:
type
TTest3<T> = ^TTest1<T>;
TTest4<T> = ^TTest2<T>;
TTest<T> = ^T;
So pointers to generics are not yet possible.
But you can do the following:
type
TMyClass = class
public
class function GetAddr<T>(const AItem: T): Pointer;
class function GetP<T>(const APtr: Pointer): T;
end;
class function TMyClass.GetAddr<T>(const AItem: T): Pointer;
begin
Result := @AItem;
end;
class function TMyClass.GetP<T>(const APtr: Pointer): T;
begin
Result := T(APtr^);
end;
You can't have generic functions, but you can have generic methods.
So with this you are able to have pointers to generics, but remember that you have no type safety using this dirty technique.
NOTE: The following answer is wrong, starting as it does from an flawed premise! Rather than redact the entire thing to save my blushes, I have left it intact so that the comments highlighting the error make sense,
How can this possibly be supported safely ?
Given (if this is what you have in mind, which I think it is):
type
TFoo<T> = class end;
PFoo<T> = ^TFoo<T>;
Then if we have:
var
a, b: TFoo<T>;
p: PFoo<T>;
a := TFoo<String>.Create;
b := TFoo<Integer>.Create;
Then both of the following would be permissible:
p := @a;
p := @b;
At any given time p might dereference to any TFoo of T, but at any given time it can only ever reference a specific T. I cannot see any type-safe compile time mechanism for ensuring that code dereferences p correctly.
One way to get around this issue (not a limitation of the compiler, but a limitation of trying to express something in a type safe way for which type safety simply cannot be expressed) would be to create type-specific derivatives of these types and use those. At the point at which you wish to dereference you are almost certainly going to know the type T anyway:
type
TFoo<T> = class end;
TFooString = TFoo<String>;
PFooString = ^TFooString;
var
p: PFooString;
a := TFoo<Integer>;
b := TFoo<String>;
p := @a; // Should not compile
p := @b; // This is OK
This is possible even in Delphi 2010.
However, worryingly, in investigating this I find that:
p := @a; // Should not compile
DOES in fact compile. Which strikes me as wrong. VERY wrong. And could point to (yet) another flaw in the generics implementation in Delphi.
Here be dragons...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With