如何根据泛型类型声明指针?

时间:2011-03-17 19:52:15

标签: delphi generics pointers parameters delphi-2010

我有一个这样的课程:

type A = class
    procedure<T> DoStuff(tPtr: ^T);
end;

但是当我尝试编译时,Delphi给了我这个错误:

[DCC Error] RPML.pas(57): E2029 Identifier expected but '^' found

如何在Delphi过程中使用指向参数化类型的指针?我不想让整个班级成为模板类。

3 个答案:

答案 0 :(得分:12)

要执行此操作,您需要在泛型类中将指针类型声明为嵌套类型:

type 
  TMyGeneric<T> = class
  type
    P = ^T;
  public
    procedure DoStuff(tPtr: P);
  end;

如果你想要一个类方法(即不是实例方法),你可以这样做:

type
  TMyGeneric<T> = record
  type
    P = ^T;
  public
    class procedure DoStuff(tPtr: P); static;
  end;

var
  int: Integer;
...
TMyGeneric<Integer>.DoStuff(@int);

或者使用var参数:

type
  TMyGeneric<T> = record
  public
    class procedure DoStuff(var a: T); static;
  end;

对于那些从未实例化的泛型类型,使用记录而不是类似乎很常见。

最后,在Delphi中,你不能没有使类通用。换句话说,没有以下C ++模板代码的类似物:

Thorsten的回答展示了如何在不使类通用的情况下实现泛型方法,这是以下C ++模板代码的Delphi模拟:

class C {
public:
   template <typename T>
   int SomeTemplateFunction(T* data) {
      printf("Address of parameter is %p\n", data);
      return 0;
   }
};

int a; 
char c; 
C cinst; 
cinst.SomeTemplateFunction<int>(&a); 
cinst.SomeTemplateFunction<char>(&c);

Thorsten的答案为您提供了一个类功能,但在评论中,您声明您正在寻找正常的成员函数。

type
  TMyClass = class
  public
    procedure DoStuff<T>(var a: T);
  end;

procedure TMyClass.DoStuff<T>(var a: T);
begin
end;

...
var
  instance: TMyClass;
  i: Integer;
  s: string;
...
  instance.DoStuff<Integer>(i);
  instance.DoStuff<string>(s);

但是,我正在努力解决的问题是,如果没有通用的解决方案,那么在Delphi中你究竟能做些什么非常有用的事情呢?

我很感激任何建议,并乐意编辑答案以适应他们。

答案 1 :(得分:4)

您可以将泛型参数从类移动到方法,并使用var而不是指针类型:

type
  TMyGeneric = record
    class procedure DoStuff<T>(var aParam: T); static;
  end;

var
  int : Integer;
  s   : string;
...
TMyGeneric.DoStuff<Integer>(int);
TMyGeneric.DoStuff<string>(s);

编辑:不幸的是,当使用var参数时,Delphi编译器似乎无法执行类型推断,这使得必须使用&lt; ..&gt;显式指定通用参数类型。关于方法调用。

没有“var”,&lt; ..&gt;可以省略(但是该方法不能再修改传入的变量)。

答案 2 :(得分:0)

type
  Pointer<T> = record
  public type
    Ty = ^T;
  end;

现在您可以在任何地方使用此通用指针

type A = class
    procedure<T> DoStuff(tPtr: Pointer<T>.Ty);
end;