【问题标题】:Can I use operator overloading to create a pointer to a generic type?我可以使用运算符重载来创建指向泛型类型的指针吗?
【发布时间】:2013-10-07 23:12:49
【问题描述】:

我正在尝试解决这个问题(以及其他一些问题。)

问题

//None of these compile
type
  PAType<T> = ^AType<T>;  
  P<T> = ^T;                
  PAType = ^AType<T>

所以我正在尝试使用记录和运算符重载来创建自己的。

我正在编写以下代码:

  TCell<T> = record
  private
    FData: T;
    procedure SetData(Value: T); inline;
    function GetData: T; inline;
  public
    property data: T read GetData write SetData;
  end;

  //Type safe pointer to T, because it knows SizeOf(T).
  P<T> = record  //wrapper around pointer: ^TCell<T>;^H^H^H^H any <T> actually 
  private
    FPointerToT: pointer;
  public
    class operator Implicit(a: pointer): P<T>; inline;
    class operator Implicit(a: P<T>): pointer; inline;
    class operator Implicit(Cell: TCell<T>): P<T>; inline;
    class operator Implicit(p: P<T>): TCell<T>; inline;
    class operator Add(a: P<T>; b: NativeUInt): P<T>; inline;
    class operator NotEqual(a,b : P<T>): Boolean; inline;
    class operator NotEqual(a: P<T>; b: pointer): Boolean; inline;
    class operator Equal(a,b : P<T>): Boolean; inline;
    class operator GreaterThan(a,b : P<T>): Boolean; inline;
    class operator GreaterThanOrEqual(a,b : P<T>): Boolean; inline;
    class operator LessThan(a,b : P<T>): Boolean; inline;
    class operator LessThanOrEqual(a,b : P<T>): Boolean; inline;
    class operator Inc(a: P<T>): P<T>; inline;
    class operator Dec(a: P<T>): P<T>; inline;
    class operator Explicit(a: P<T>): T; inline;
  end;

我正在写一个哈希表。因为我正在尝试不同的哈希选项。
哈希表应该获取一条带有数据的记录,将记录放入动态数组中(记录本身,不是指针)并返回指向该记录的指针。

这将允许应用程序以或多或少的顺序存储数据(有一些间隙)。这对缓存有好处。
我想使用泛型,因为即使哈希表在任何时候只保存一种类型,在不同的哈希表中也有不同的类要进行哈希处理。

通过返回一个指针,我可以防止双重存储。

上面未完成的结构让我可以这样写代码:

//FCells: array of T;
//FArrayEnd: pointer; //points to element FCells[max_elements+1] (i.e. access violation)  

function THashTable<K, T>.NextItem(Item: P<T>): P<T>;
begin
  Result:= Item + SizeOf(T);  //pointer arithmetic 
  if Result >= FArrayEnd then Result:= @FCells[0];  //comparison and assignment
end;

function THashTable<K, T>.Lookup(const key: K): P<T>;
var
  Index: NativeUInt;
  ItemKey: K;
begin
  if IsValid(key) then begin
    // Check regular cells
    Index:= First_Cell(FGetHashFromKey(key));  //FGet.. is a user supplied key generation proc.
    while (true) do begin
      ItemKey:= FGetKey(FCells[Index]);
      if (IsEqual(ItemKey, key)) then exit(@FCells[Index]);
      if (IsEmpty(ItemKey)) then exit(nil);  //nil pointers denote no-hit 
      Index:= NextIndex(Index);
    end;
  end
  else { if IsEmpty(key) then } begin
    // Check zero cell
    Result:= @FZeroCell;
  end;
end;

请注意,我不需要Nullable&lt;T&gt; 来表示错过。我标准的nil 指针有效。

我不必进行类型转换,并且指针知道它有多大。
它甚至对 什么 T 有一点了解。

我知道泛型有很多问题,所以:

在我深入研究之前。
这会奏效(原则上)还是这种方法只是一厢情愿?

【问题讨论】:

  • 我在这里无法辨别问题。你的实际问题是什么?是什么让你说“没有指向泛型类型的指针很糟糕。”
  • 别担心,我会在找到最小的工作解决方案后立即自行回答。
  • 在没有解决问题的情况下不要这样做。我真的很感兴趣。请务必告诉我们您发现了什么限制。
  • type PGeneric = ^T type PSomething = ^TMyClass<T> type PMyRecord<T> = ^MyRecord<T> 不编译。你明白了。 我希望能够传递指向类型 T 的指针,比一般的无类型指针更智能
  • 简而言之,它试图解决 Delphi 不允许我声明指向通用类型、-class 或 -record 的指针这一事实。

标签: delphi generics pointers operator-overloading delphi-xe2


【解决方案1】:

您可以拥有指向泛型类型的指针。像这样:

type
  THashTable<K, T> = class
  public type
    TCell = TCell<T>;
    PCell = ^TCell;
  public
    function NextItem(Item: PCell): PCell;
  end;

要实现指针算法,您需要以下代码:

function THashTable<K, T>.NextItem(Item: PCell): PCell;
begin
  Result := Item;
  inc(Result);
end;

【讨论】:

  • 我知道这个技巧,但是尝试在类的外部声明指针,它不会起作用。我需要能够在另一个类/单元中使用指针 type
  • 当你制定出要求后,请把它们放在问题中。无论如何,您可以在类型之外使用该类型。是THashTable&lt;K, T&gt;.PCell
  • 等一下,TCellPCell 类型是否随处可用?是的,他们是,这很酷。
  • Ehmm 这也适用于记录吗?我需要它来记录。 TCell&lt;T&gt; = record ..... PCell = ^TCell
  • 我看不出它为什么不能用于记录。您的所有要求都在 cmets 中溢出! ;-)
猜你喜欢
  • 2011-06-06
  • 2022-11-18
  • 2010-10-22
  • 2019-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-27
相关资源
最近更新 更多